Skip to main content

go-zero 配置概述

概述

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

如何使用

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

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

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

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

具体使用例子:

package main

import (
"flag"

"github.com/zeromicro/go-zero/core/conf"
)

type Config struct {
Host string `json:",default=0.0.0.0"`
Port int
}

var f = flag.String("f", "config.yaml", "config file")

func main() {
flag.Parse()
var c Config
conf.MustLoad(*f, &c)
println(c.Host)
}

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

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

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

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

其他格式的配置文件

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

  • json
  • yaml | yml
  • toml

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

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


func LoadFromJsonBytes(content []byte, v interface{}) error

func LoadFromTomlBytes(content []byte, v interface{}) error

func LoadFromYamlBytes(content []byte, v interface{}) error

简单示例:

text := []byte(`a: foo
B: bar`)

var val struct {
A string
B string
}
_ = LoadFromYamlBytes(text, &val)
注意

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

大小写不敏感

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

Host: "127.0.0.1"

host: "127.0.0.1"

环境变量

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

1. conf.UseEnv()


var c struct {
Name string
}

conf.MustLoad("config.yaml", &c, conf.UseEnv())

Name: ${SERVER_NAME}

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

2. env Tag

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

var c struct {
Name string `json:",env=SERVER_NAME"`
}

conf.MustLoad("config.yaml", &c)

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

注意

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

tag 校验规则

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

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

如果我们在 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"`
range 表达式值规则
  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就可以了。 如下的例子

type Config struct {
Etcd discov.EtcdConf
UserRpc zrpc.RpcClientConf
PortRpc zrpc.RpcClientConf
OtherRpc zrpc.RpcClientConf
}

const str = `
Etcd:
Key: rpcServer"
Hosts:
- "127.0.0.1:6379"
- "127.0.0.1:6377"
- "127.0.0.1:6376"

UserRpc:
Etcd:
Key: UserRpc
Hosts:
- "127.0.0.1:6379"
- "127.0.0.1:6377"
- "127.0.0.1:6376"

PortRpc:
Etcd:
Key: PortRpc
Hosts:
- "127.0.0.1:6379"
- "127.0.0.1:6377"
- "127.0.0.1:6376"

OtherRpc:
Etcd:
Key: OtherRpc
Hosts:
- "127.0.0.1:6379"
- "127.0.0.1:6377"
- "127.0.0.1:6376"
`

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

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

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

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

const str = `
Etcd:
Key: rpcServer"
Hosts:
- "127.0.0.1:6379"
- "127.0.0.1:6377"
- "127.0.0.1:6376"

UserRpc:
Etcd:
Key: UserRpc

PortRpc:
Etcd:
Key: PortRpc

OtherRpc:
Etcd:
Key: OtherRpc
`