先看go-zero的rpc和api的目录结构
rpc:
api:
不管是API目录 还是在RPC目录下 配置文件存放方式都是一样的 在etc目录下有一个 yaml文件,在internal\config目录下有一个config.go 文件。
查看yaml文件
Name: user
Host: 0.0.0.0
Port: 8282
Mysql:
DataSource: user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=true
查看config.go文件
package config
import "github.com/tal-tech/go-zero/rest"
type Config struct {
rest.RestConf
Mysql struct {
DataSource string
}
}
再查看rest.RestConf文件
RestConf struct {
service.ServiceConf
Host string `json:",default=0.0.0.0"`
Port int
CertFile string `json:",optional"`
KeyFile string `json:",optional"`
Verbose bool `json:",optional"`
MaxConns int `json:",default=10000"`
MaxBytes int64 `json:",default=1048576"`
// milliseconds
Timeout int64 `json:",default=3000"`
CpuThreshold int64 `json:",default=900,range=[0:1000]"`
Signature SignatureConf `json:",optional"`
}
gozero在初始化的时候加载配置文件其实就是将Yaml中的信息 映射到config.go中,如果操作的呢 先看下初始化代码
查看api下的user.go
var configFile = flag.String("f", "etc/user.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
server := rest.MustNewServer(c.RestConf)
defer server.Stop()
handler.RegisterHandlers(server, ctx)
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
server.Start()
}
go-zero主要是通过 conf.MustLoad(*configFile, &c) 这个方法去做映射,当然你也可以不用默认的etc/user.yaml 通过-f参数你可以用任何您想要映射的配置文件
我们再看下conf.MustLoad这个方法
// MustLoad loads config into v from path, exits on error.
func MustLoad(path string, v interface{}, opts ...Option) {
if err := LoadConfig(path, v, opts...); err != nil {
log.Fatalf("error: config file %s, %s", path, err.Error())
}
}
有三个参数
path:string类型 就是我们刚才yaml文件的路径地址
v: interface{} 就是我们刚才的cofig.go ,配置映射的载体
opts: 自定义的Option方法
主要是LoadConfig方法
var loaders = map[string]func([]byte, interface{}) error{
".json": LoadConfigFromJsonBytes,
".yaml": LoadConfigFromYamlBytes,
".yml": LoadConfigFromYamlBytes,
}
// LoadConfig loads config into v from file, .json, .yaml and .yml are acceptable.
func LoadConfig(file string, v interface{}, opts ...Option) error {
content, err := ioutil.ReadFile(file)
if err != nil {
return err
}
loader, ok := loaders[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)
}
第10-13行: 读取配置文件的内容 获取的类型为[]byte
第15-18行: 获取配置文件的格式,在loaders中定义了三种格式并且指定了将[]byte映射到struct的方法;可以看到目前仅支持json,yaml,yml三种文件格式
第20-27行: 这里主要是通过自定义的opts方法设置 配置是否走环境变量,如果走环境变量就取环境变量中的信息不从配置文件走了
第29行: 将配置文件信息映射到结构体中
// LoadConfigFromJsonBytes loads config into v from content json bytes.
func LoadConfigFromJsonBytes(content []byte, v interface{}) error {
return mapping.UnmarshalJsonBytes(content, v)
}
// LoadConfigFromYamlBytes loads config into v from content yaml bytes.
func LoadConfigFromYamlBytes(content []byte, v interface{}) error {
return mapping.UnmarshalYamlBytes(content, v)
}