go-zero 配置概述

概述

go-zero 提供了一个强大的 conf 包用于加载配置。我们目前支持的 yaml, json, toml 3 种格式的配置文件,go-zero 通过文件后缀会自行加载对应的文件格式。

如何使用

我们使用 github.com/zeromicro/go-zero/core/conf conf 包进行配置的加载。

第一步我们会定义我们的配置结构体,其中定义我们所有需要的依赖。

第二步接着根据配置编写我们对应格式的配置文件。

第三步通过 conf.MustLoad 加载配置。

具体使用例子:

  • main.go
  • config.yaml
  1. package main
  2. import (
  3. "flag"
  4. "github.com/zeromicro/go-zero/core/conf"
  5. )
  6. type Config struct {
  7. Host string `json:",default=0.0.0.0"`
  8. Port int
  9. }
  10. var f = flag.String("f", "config.yaml", "config file")
  11. func main() {
  12. flag.Parse()
  13. var c Config
  14. conf.MustLoad(*f, &c)
  15. println(c.Host)
  16. }
  1. Host: 127.0.0.1
  2. Port: 8888

我们一般会在程序启动的时候进行配置的加载,同时我们一般也需要定义我们配置所需要的结构体, 在 go-zero 中,我们推荐将所有服务依赖都定义在 config 中,这样以后配置根据 config 就可以查找出所有的依赖。

我们使用 func MustLoad(path string, v interface{}, opts …Option) 进行加载配置,path 为配置的路径,v 为结构体。 这个方法会完成配置的加载,如果配置加载失败,整个程序会 fatal 停止掉。

当然我们也提供了其他的加载方式,例如:

  1. func Load(file string, v interface{}, opts ...Option) error

其他格式的配置文件

我们目前支持的配置格式如下:

  • json
  • yaml | yml
  • toml

我们程序会自动通过文件后缀进行对应格式的加载。

当然我们在 conf 包中也提供了对应格式二进制数据加载的方法:

  1. func LoadFromJsonBytes(content []byte, v interface{}) error
  2. func LoadFromTomlBytes(content []byte, v interface{}) error
  3. func LoadFromYamlBytes(content []byte, v interface{}) error

简单示例:

  1. text := []byte(`a: foo
  2. B: bar`)
  3. var val struct {
  4. A string
  5. B string
  6. }
  7. _ = LoadFromYamlBytes(text, &val)
go-zero 配置概述 - 图1注意

对于有些需要自定义 tag 的,为了方便统一,我们目前所有 tag 均为 json tag。

大小写不敏感

conf 目前已经默认自动支持 key 大小写不敏感,例如对应如下的配置我们都可以解析出来:

  1. Host: "127.0.0.1"
  2. host: "127.0.0.1"

环境变量

目前 conf 配置支持环境变量注入,我们有 2 种方式实现

1. conf.UseEnv()

  1. var c struct {
  2. Name string
  3. }
  4. conf.MustLoad("config.yaml", &c, conf.UseEnv())
  1. Name: ${SERVER_NAME}

如上,我们在 Load 时候传入 UseEnv, conf 会自动根据值替换字符串中的${var}或$var 当前环境变量。

2. env Tag

注意 env 需要 go-zero v1.4.3 以上版本才支持。

  1. var c struct {
  2. Name string `json:",env=SERVER_NAME"`
  3. }
  4. conf.MustLoad("config.yaml", &c)

我们可以在 json tag 的后面加上 env=SERVER_NAME 的标签,conf 将会自动去加载对应的环境变量。

go-zero 配置概述 - 图2注意

我们配置加载的顺序会优先级 env > 配置中的定义 > json tag 中的 default 定义

tag 校验规则

我们可以通过在 tag 中来声明参数接收规则,除此之外,还支持参数的校验,参数校验的规则写在 tag value 中,简单示例如下:

  1. type Config struct {
  2. Name string // 没有任何 tag,表示配置必填
  3. Port int64 `json:",default=8080"` // 如果配置中没有配置,将会初始成 8080
  4. Path string `json:",optional"`
  5. }

如果我们在 conf 加载的时候,验证没有通过,将会报出来对应的错误。

目前 go-zero 支持的校验规则如下:

接收规则说明示例
optional当前字段是可选参数,允许为零值(zero value)json:"foo,optional"
options当前参数仅可接收的枚举值写法 1:竖线\
default当前参数默认值json:"gender,default=male"
range当前参数数值有效范围,仅对数值有效,写法规则详情见下文温馨提示json:"age,range=[0:120]"
env当前参数从环境变量获取json:"mode,env=MODE"
go-zero 配置概述 - 图3range 表达式值规则
  1. 左开右闭区间:(min:max],表示大于 min 小于等于 max,当 min 缺省时,min 代表数值 0,当 max 缺省时,max 代表无穷大,min 和 max 不能同时缺省
  2. 左闭右开区间:[min:max),表示大于等于 min 小于 max,当 max 缺省时,max 代表数值 0,当 min 缺省时,min 代表无穷大,min 和 max 不能同时缺省
  3. 闭区间:[min:max],表示大于等于 min 小于等于 max,当 min 缺省时,min 代表数值 0,当 max 缺省时,max 代表无穷大,min 和 max 不能同时缺省
  4. 开区间:(min:max),表示大于 min 小于 max,当 min 缺省时,min 代表数值 0,当 max 缺省时,max 代表无穷大,min 和 max 不能同时缺省

更多可以参考 unmarshaler_test.go

inherit 配置继承

在我们日常的配置,会出现很多重复的配置,例如 rpcClientConf 中,每个 rpc 都有一个 etcd 的配置,但是我们大部分的情况下 etcd 的配置都是一样的,我们希望可以只用配置一次etcd就可以了。 如下的例子

  1. type Config struct {
  2. Etcd discov.EtcdConf
  3. UserRpc zrpc.RpcClientConf
  4. PortRpc zrpc.RpcClientConf
  5. OtherRpc zrpc.RpcClientConf
  6. }
  7. const str = `
  8. Etcd:
  9. Key: rpcServer"
  10. Hosts:
  11. - "127.0.0.1:6379"
  12. - "127.0.0.1:6377"
  13. - "127.0.0.1:6376"
  14. UserRpc:
  15. Etcd:
  16. Key: UserRpc
  17. Hosts:
  18. - "127.0.0.1:6379"
  19. - "127.0.0.1:6377"
  20. - "127.0.0.1:6376"
  21. PortRpc:
  22. Etcd:
  23. Key: PortRpc
  24. Hosts:
  25. - "127.0.0.1:6379"
  26. - "127.0.0.1:6377"
  27. - "127.0.0.1:6376"
  28. OtherRpc:
  29. Etcd:
  30. Key: OtherRpc
  31. Hosts:
  32. - "127.0.0.1:6379"
  33. - "127.0.0.1:6377"
  34. - "127.0.0.1:6376"
  35. `

我们必须为每个 Etcd 都要加上 Hosts 等基础配置。

但是如果我们使用了 inherit 的tag 定义,使用的方式在tag 中加上 inherit。如下:

  1. // A RpcClientConf is a rpc client config.
  2. RpcClientConf struct {
  3. Etcd discov.EtcdConf `json:",optional,inherit"`
  4. ....
  5. }

这样我们就可以简化 Etcd 的配置,他会自动向上一层寻找配置。

  1. const str = `
  2. Etcd:
  3. Key: rpcServer"
  4. Hosts:
  5. - "127.0.0.1:6379"
  6. - "127.0.0.1:6377"
  7. - "127.0.0.1:6376"
  8. UserRpc:
  9. Etcd:
  10. Key: UserRpc
  11. PortRpc:
  12. Etcd:
  13. Key: PortRpc
  14. OtherRpc:
  15. Etcd:
  16. Key: OtherRpc
  17. `