解决使用go-zero加载配置出现bug的问题

项目场景:

go-zero作为框架开发,使用他原生的解析方法进行配置解析


问题描述

添加自己定义的配置发现解析不正确:


这是我的配置文件,自己添加了一个数据库的配置

type TDengineSetting struct {
	Server         string `yaml:"server"`          //TDengine服务地址
	UserName       string `yaml:"user_name"`       //用户名
	Password       string `yaml:"password"`        //密码
	Port           int32  `yaml:"port"`            //端口
	ConnectionType string `yaml:"connection_type"` //连接类型,原生或者restful
	DbName         string `yaml:"db_name"`
}

这是我的解析,这样来看完全没问题,yaml是对得上的


原因分析:

首先我们要知道go-zero的解析在哪里进行。代码是这个:

conf.MustLoad(*configFile, &config.GlobalConfig)

然后我们一步一步点进去看里面的逻辑,看MustLoad方法

// MustLoad loads config into v from path, exits on error.
func MustLoad(path string, v interface{}, opts ...Option) {
	if err := Load(path, v, opts...); err != nil {
		log.Fatalf("error: config file %s, %s", path, err.Error())
	}
}

就一个Load函数在里面,继续下一步,看Load

// Load loads config into v from file, .json, .yaml and .yml are acceptable.
func Load(file string, v interface{}, opts ...Option) error {
	content, err := os.ReadFile(file)
	if err != nil {
		return err
	}

	loader, ok := loaders[strings.ToLower(path.Ext(file))]
	if !ok {
		return fmt.Errorf("unrecognized file type: %s", file)
	}

	var opt options
	for _, o := range opts {
		o(&opt)
	}

	if opt.env {
		return loader([]byte(os.ExpandEnv(string(content))), v)
	}

	return loader(content, v)
}

最后两步他执行了loader函数,但是是函数回调,回调前他是通过loadersMap进行赋值的,进去loaders看看

var loaders = map[string]func([]byte, interface{}) error{
	".json": LoadFromJsonBytes,
	".toml": LoadFromTomlBytes,
	".yaml": LoadFromYamlBytes,
	".yml":  LoadFromYamlBytes,
}

差不多要浮出水面了,我的是yaml文件,进去LoadFromYamlBytes看看

// LoadFromYamlBytes loads config into v from content yaml bytes.
func LoadFromYamlBytes(content []byte, v interface{}) error {
	b, err := encoding.YamlToJson(content)
	if err != nil {
		return err
	}

	return LoadFromJsonBytes(b, v)
}

发现他是先把yaml转成json再调用LoadFromJsonBytes方法进行解析的,这不扯淡嘛,还是得回到json,进去YamlToJson看看

func YamlToJson(data []byte) ([]byte, error) {
	var val interface{}
	if err := yaml.Unmarshal(data, &val); err != nil {
		return nil, err
	}

	val = toStringKeyMap(val)

	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(val); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

这里就发现问题所在了,这里用son.NewEncoder(&buf).Encode(val)去序列化我的配置信息,但我的配置没有设置json标签的,他就会把json默认是标识符,我的标识符全是大写开头的,例如:Server; 但是我的配置文件写的yaml标签是小写开头的,所以就出现了配置加载不上的问题


解决方案:

有两个解决办法
一、所有的配置都采用大写开头,不用写yaml标签都能解析成功,作者使用的是这个方法
二、解析的结构体标签增加多一个json标签,对应着yaml文件的配置,此方法不推荐,作者也没尝试过,如有问题,欢迎评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用go-zero和Terraform实现自动化云平台部署的项目,可以分为以下几个步骤: 1. 安装go-zero和Terraform 在开始之前,您需要确保已经安装了go-zero和Terraform。您可以从官方网站下载和安装它们。 2. 创建go-zero项目 使用goctl命令创建一个新的go-zero项目: ``` goctl api new your_project ``` 这将在当前目录中创建一个新的go-zero项目。 3. 编写go-zero服务代码 在项目目录中,您可以使用goctl命令来创建一个新的服务: ``` goctl api add -plugin tf your_service ``` 这将在services目录中创建一个新的服务,该服务将使用Terraform插件。 现在,您可以在该服务中编写自己的业务逻辑代码。 4. 编写Terraform代码 在该服务的tf目录中,您可以编写Terraform代码来定义您的基础设施。 例如,您可以使用Terraform代码来定义一个新的云服务器实例: ``` resource "aws_instance" "example" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" tags = { Name = "example-instance" } } ``` 5. 编写自动化脚本 最后,您可以编写一个自动化脚本来自动化部署您的服务和基础设施。 例如,您可以使用bash脚本来自动化部署: ``` #!/bin/bash # 编译服务 go build -o your_service # 初始化Terraform terraform init # 应用Terraform配置 terraform apply -auto-approve ``` 这将自动编译您的服务并应用您的Terraform配置来创建您的基础设施。 总之,使用go-zero和Terraform实现自动化云平台部署的项目可以简化部署流程并提高效率。但是,在使用自动化工具之前,您需要了解基础设施和自动化工具的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值