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

相关推荐
无籽西瓜a13 分钟前
【西瓜带你学设计模式 | 第十一期 - 模板方法模式】模板方法模式 —— 流程骨架与钩子实现、优缺点与适用场景
java·后端·设计模式·软件工程·模板方法模式
牛奔13 分钟前
g:Go 版本管理器安装与使用指南
开发语言·后端·golang
chenglin01621 分钟前
Semantic Kernel 内核详解
后端·python·flask
青柠代码录2 小时前
【SpringCloud】Nacos 组件:服务注册与发现
后端
2401_8955213411 小时前
SpringBoot Maven快速上手
spring boot·后端·maven
disgare11 小时前
关于 spring 工程中添加 traceID 实践
java·后端·spring
ictI CABL11 小时前
Spring Boot与MyBatis
spring boot·后端·mybatis
小江的记录本13 小时前
【Linux】《Linux常用命令汇总表》
linux·运维·服务器·前端·windows·后端·macos
yhole16 小时前
springboot三层架构详细讲解
spring boot·后端·架构
香香甜甜的辣椒炒肉16 小时前
Spring(1)基本概念+开发的基本步骤
java·后端·spring