在 Kratos 项目中,配置源可以指定多个,并且 config 会进行合并成 key/value 。 然后用户通过 Scan 或者 Value 获取对应键值内容,主要功能特性:

  • 默认实现了本地文件数据源。
  • 用户可以自定义数据源实现。
  • 支持配置热加载,以及通过 Atomic 方式变更已有 Value。
  • 支持自定义数据源解码实现。
  • 支持通过通过占位符$获取环境变量或已有字段的值

通过 proto 定义配置

在 Kratos 项目中,我们默认推荐通过 proto 进行定义配置文件,主要有以下几点好处:

  • 可以定义统一的模板配置
  • 添加对应的配置校验
  • 更好地管理配置
  • 跨语言支持

配置文件

  1. server:
  2. http:
  3. addr: 0.0.0.0:8000
  4. timeout: 1s
  5. grpc:
  6. addr: 0.0.0.0:9000
  7. timeout: 1s
  8. data:
  9. database:
  10. driver: mysql
  11. source: root:root@tcp(127.0.0.1:3306)/test
  12. redis:
  13. addr: 127.0.0.1:6379
  14. read_timeout: 0.2s
  15. write_timeout: 0.2s

proto 声明

  1. syntax = "proto3";
  2. package kratos.api;
  3. option go_package = "github.com/go-kratos/kratos-layout/internal/conf;conf";
  4. import "google/protobuf/duration.proto";
  5. message Bootstrap {
  6. Server server = 1;
  7. Data data = 2;
  8. }
  9. message Server {
  10. message HTTP {
  11. string network = 1;
  12. string addr = 2;
  13. google.protobuf.Duration timeout = 3;
  14. }
  15. message GRPC {
  16. string network = 1;
  17. string addr = 2;
  18. google.protobuf.Duration timeout = 3;
  19. }
  20. HTTP http = 1;
  21. GRPC grpc = 2;
  22. }
  23. message Data {
  24. message Database {
  25. string driver = 1;
  26. string source = 2;
  27. }
  28. message Redis {
  29. string network = 1;
  30. string addr = 2;
  31. google.protobuf.Duration read_timeout = 3;
  32. google.protobuf.Duration write_timeout = 4;
  33. }
  34. Database database = 1;
  35. Redis redis = 2;
  36. }

使用方式

配置源可以指定多个,并且 config 会进行合并成 map[string]interface{},然后通过 Scan 或者 Value 获取值内容;目前支持的配置源:

  • file
  • env
  1. c := config.New(
  2. config.WithSource(
  3. file.NewSource(path),
  4. ),
  5. config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
  6. // kv.Key
  7. // kv.Value
  8. // kv.Format
  9. // 自定义实现对应的数据源解析,如果是配置中心数据源也可以指定对应的 format 进行识别配置类型
  10. return yaml.Unmarshal(kv.Value, v)
  11. }),
  12. config.WithResolver(func(map[string]interface{}) error {
  13. // 默认 resolver 提供了对 ${key:default} 与 $key 两种占位符的处理
  14. // 自定义加载配置数据后的处理方法
  15. })
  16. )
  17. // 加载配置源:
  18. if err := c.Load(); err != nil {
  19. log.Fatal(err)
  20. }
  21. // 获取对应的值内容:
  22. name, err := c.Value("service").String()
  23. /*
  24. 通过 proto 文件生成的结构体,也可以直接声明结构体进行解析如:
  25. var v struct {
  26. Service string `json:"service"`
  27. Version string `json:"version"`
  28. }
  29. */
  30. var bc conf.Bootstrap
  31. if err := c.Scan(&bc); err != nil {
  32. log.Fatal(err)
  33. }
  34. // 监听某个键值内容变更
  35. c.Watch("service.name", func(key string, value config.Value) {
  36. // 值内容变更
  37. })

Kratos可以通过配置文件中的占位符来读取环境变量或者已有字段的Value

  1. service:
  2. name: "kratos_app"
  3. http:
  4. server:
  5. # 使用 service.name 的值
  6. name: "${service.name}"
  7. # 使用环境变量 PORT 替换,若不存在,使用默认值 8080
  8. port: "${PORT:8080}"
  9. # 使用环境变量 TIMEOUT 替换,无默认值
  10. timeout: "$TIMEOUT"

加载来自环境变量的配置源时需要提前加载,保证读取配置文件时对应环境变量已被加载

  1. c := config.New(
  2. config.WithSource(
  3. // 在file之前添加前缀为 KRATOS_ 的环境变量
  4. env.NewSource("KRATOS_"),
  5. // 添加配置文件
  6. file.NewSource(path),
  7. ))
  8. // 加载配置源:
  9. if err := c.Load(); err != nil {
  10. log.Fatal(err)
  11. }
  12. // 获取环境变量 KRATOS_PORT 的值
  13. port, err := c.Value("PORT").String()