不仅java要接入apollo,golang我也要接入apollo

这里是weihubeats ,觉得文章不错可以关注公众号小奏技术

背景

最近有个golang服务要接入apollo,所以要研究下apollogolang接入方式

发现官方提供了agollogolang sdk

实际维护频率也处于比较低频的状态

接入步骤

  1. 引入依赖
shell 复制代码
go get -u github.com/apolloconfig/agollo/v4@latest
  1. 从apollo读取配置信息

我这里先总结下大致步骤,后面会给出完整代码

a. 构建*config.AppConfig

b. 通过*config.AppConfig读取到一个string对象(properties),即所有配置文件(官方不支持yaml的直接读取)

c. 将properties转换为map[string]interface{}对象

2-4. 将map[string]interface{}对象转换为yaml对象

如果只需要读取properties文件,可以直接使用agollo提供的GetContent方法,之后无需进行其他转换

完整代码

golang 复制代码
 const (
	envApolloAddr    = "APOLLO_ADDR"
	envApolloAppID   = "APOLLO_APP_ID"
	envApolloCluster = "APOLLO_CLUSTER"

	defaultApolloAddr = "http://127.0.0.1:8080"
	defaultAppID      = "小奏技术"
	defaultNamespace  = "xiaozou.yaml"
)

func readConfigByApollo() *Config {
	c := getApolloConfig()

	client, err := agollo.StartWithConfig(func() (*config.AppConfig, error) {
		return c, nil
	})
	if err != nil {
		panic(err)
	}
	configYAML := client.GetConfig(defaultNamespace).GetContent()

	propMap, err := propertiesToMap(configYAML)
	if err != nil {
		panic(err)
	}
	// 将map转换为YAML字节流
	yamlBytes, err := yaml.Marshal(propMap)
	if err != nil {
		panic(err)
	}

	var apolloConfig *Config
	err = yaml.Unmarshal(yamlBytes, &apolloConfig)
	if err != nil {
		_ = fmt.Errorf(err.Error())
		panic(err)
	}

	// 打印解析后的配置,或者进行后续处理
	fmt.Printf("Config: %+v\n", apolloConfig)

	return apolloConfig

}

func getApolloConfig() *config.AppConfig {
	apolloAddr := os.Getenv(envApolloAddr)
	if apolloAddr == "" {
		apolloAddr = defaultApolloAddr
	}
	fmt.Printf("apollo addr: %s\n", apolloAddr)

	appID := os.Getenv(envApolloAppID)

	if appID == "" {
		appID = defaultAppID
	}

	namespace := os.Getenv(envApolloCluster)
	if namespace == "" {
		namespace = defaultNamespace
	}
	c := &config.AppConfig{
		AppID:          appID,
		Cluster:        "default",
		NamespaceName:  namespace,
		IP:             apolloAddr,
		IsBackupConfig: true,
		Secret:         "",
	}
	return c
}

func propertiesToMap(properties string) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	lines := strings.Split(properties, "\n")
	for _, line := range lines {
		if line == "" || strings.HasSuffix(line, "#") {
			continue
		}
		parts := strings.SplitN(line, "=", 2)
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid property format: %s", line)
		}
		// 处理嵌套
		value := parseValue(parts[1])
		keys := strings.Split(parts[0], ".")
		lastMap := result
		for i, key := range keys {
			if i == len(keys)-1 {
				lastMap[key] = value
			} else {
				if _, ok := lastMap[key]; !ok {
					lastMap[key] = make(map[string]interface{})
				}
				lastMap = lastMap[key].(map[string]interface{})
			}
		}
	}
	return result, nil

}

func parseValue(str string) interface{} {

	if str == "true" || str == "True" {
		return true
	} else if str == "false" || str == "False" {
		return false
	}
	if i, err := strconv.Atoi(str); err == nil {
		return i
	}

	if strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]") {
		str = str[1 : len(str)-1] // 移除括号
		if str == "" {
			return []string{}
		}
		// 分割字符串,并去除每个元素周围的空格
		elements := strings.Split(str, ",")
		for i, el := range elements {
			elements[i] = strings.TrimSpace(el)
		}
		return elements
	}

	// 返回原始字符串
	return str

}

上面的Config结构体如下

golang 复制代码
type Config struct {
	Server  *Server                   `yaml:"server"`
	Log     *Log                      `yaml:"log"`
	Topic   *Topic                    `yaml:"topic"`
	Configs map[string]RocketmqConfig `yaml:"rocketmq"`
}

yaml处理使用是github.com/go-yaml/yam...

相关推荐
我这一拳20年的功力11 小时前
深入解析 XXL-JOB 核心原理:从 Quartz 到自研时间轮
后端
MgArcher11 小时前
一个下划线表示“别动”,两个下划线表示“真别动”!Python属性访问控制,看懂这篇就够了
后端
ltl11 小时前
【大模型基础设施工程】19:Agent 框架工程
后端
Leinwin11 小时前
Claude 四月宕机七次:从一次事故看企业级 AI 部署的容灾设计
后端·python·flask
是希燃亚11 小时前
hermes迁移手册,将hermes迁移到不同服务器~
后端·github
山水洛行11 小时前
切实有效的RAG文本分块:语义分割、上下文重叠与评估驱动调优
后端
审判长烧鸡11 小时前
GO错误处理【3】返回err与日志的结合
go·架构设计·报错处理
蜜獾云11 小时前
系统国际化之多语言解决方案
后端
SamDeepThinking12 小时前
第2篇:应付百万并发商品系统之需求文档
java·后端·架构
直奔標竿12 小时前
Java开发者AI转型第二十课!Spring AI MCP 双向实战:客户端与服务端手把手落地
java·开发语言·人工智能·spring boot·后端·spring