不仅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...

相关推荐
一弓虽11 分钟前
SpringBoot 学习
java·spring boot·后端·学习
姑苏洛言20 分钟前
扫码小程序实现仓库进销存管理中遇到的问题 setStorageSync 存储大小限制错误解决方案
前端·后端
光而不耀@lgy35 分钟前
C++初登门槛
linux·开发语言·网络·c++·后端
方圆想当图灵1 小时前
由 Mybatis 源码畅谈软件设计(七):SQL “染色” 拦截器实战
后端·mybatis·代码规范
毅航1 小时前
MyBatis 事务管理:一文掌握Mybatis事务管理核心逻辑
java·后端·mybatis
我的golang之路果然有问题2 小时前
速成GO访问sql,个人笔记
经验分享·笔记·后端·sql·golang·go·database
柏油2 小时前
MySql InnoDB 事务实现之 undo log 日志
数据库·后端·mysql
写bug写bug3 小时前
Java Streams 中的7个常见错误
java·后端
Luck小吕4 小时前
两天两夜!这个 GB28181 的坑让我差点卸载 VSCode
后端·网络协议
M1A14 小时前
全栈开发必备:Windows安装VS Code全流程
前端·后端·全栈