Kratos配置加载必须显式执行New→Load→Scan三步:New仅创建实例,Load才读取原始数据,Scan才绑定结构体;遗漏Load会导致Scan panic或零值,且需defer c.Close()防goroutine泄漏。

Kratos 框架本身不强制绑定任何配置格式或来源,配置服务的关键在于组合 config.Source 与 config.New(),再通过 Load() 和 Scan() 完成加载与结构体绑定——不是“写一个配置文件就自动生效”,而是你得显式构造并驱动它。
配置加载三步必须写全:New → Load → Scan
常见错误是只调用 New() 就以为配置已就绪,结果 Scan() 时报空指针或字段零值。Kratos 的 config.Config 是惰性加载的,Load() 才真正读取原始数据,Scan() 才解析进结构体。
-
config.New()只创建实例,不触发任何 I/O -
Load()必须在Scan()前调用,否则Scan()会 panic 或返回err != nil - 记得
defer c.Close(),尤其当 Source 启用了 Watch(如 etcd)时,不 Close 会导致 goroutine 泄漏
文件配置:path 参数必须指向具体文件,不是目录
用 file.NewSource(flagconf) 时,flagconf 值必须是完整路径+文件名,比如 "configs/config.yaml",不能是 "configs/"。否则 Load() 会静默失败(返回空 KeyValue 列表),后续 Scan() 绑定不到任何字段。
- 支持格式:YAML、JSON、TOML、Properties(扩展名决定解析器)
- 若文件不存在或权限不足,
Load()直接返回 error,不会 fallback 到默认值 - 多个文件可叠加传入:
file.NewSource("a.yaml"), file.NewSource("b.json"),后加载的覆盖前加载的同 key
etcd 配置源:path 和 prefix 决定键匹配行为
使用 etcd/v3 Source 时,cfg.WithPath("/app-config") 是必填项,但它的语义取决于是否启用 cfg.WithPrefix(true):
-
WithPrefix(false)(默认):只监听精确匹配的单个 key,比如/app-config -
WithPrefix(true):监听以该 path 为前缀的所有子 key,比如/app-config/http/port、/app-config/grpc/timeout - etcd 中存储的值必须是纯字符串,Kratos 不自动做类型转换;YAML 结构需自己序列化后存入(或用
json.Marshal)
环境变量优先级:env.NewSource() 要放 Source 列表末尾
环境变量通常用于覆盖配置文件中的值,所以要把 env.NewSource() 放在 config.WithSource() 的参数最后。Kratos 按 Source 传入顺序合并,后入者覆盖先入者同名 key。
- 环境变量 key 名需全大写、下划线分隔,如
HTTP_SERVER_ADDRESS对应配置结构体中Http.Server.Address - 不支持嵌套结构体的点号写法(如
HTTP.SERVER.ADDRESS),只认下划线 - 如果同时用了文件和 env,建议在开发时用文件提供默认值,用 env 在部署时覆盖敏感或环境相关字段
最易被忽略的是:所有 Source 实现(包括 etcd、k8s、apollo)都只负责把原始字节流转成 config.KeyValue,真正的类型解析、嵌套展开、默认值填充,全靠 Scan() 时的结构体 tag(如 yaml:"http.server.address")和反射逻辑。一旦结构体字段名或 tag 写错,就不会绑定——而错误往往静默发生,只能靠日志或调试确认 KeyValue 是否被正确加载进来。











