github.com/zly-app/zapp@v1.3.3/config/readme.md (about) 1 2 <!-- TOC --> 3 4 - [配置说明](#%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E) 5 - [配置加载方式](#%E9%85%8D%E7%BD%AE%E5%8A%A0%E8%BD%BD%E6%96%B9%E5%BC%8F) 6 - [从文件加载配置](#%E4%BB%8E%E6%96%87%E4%BB%B6%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE) 7 - [框架配置示例](#%E6%A1%86%E6%9E%B6%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B) 8 - [插件配置示例](#%E6%8F%92%E4%BB%B6%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B) 9 - [服务配置示例](#%E6%9C%8D%E5%8A%A1%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B) 10 - [组件配置示例](#%E7%BB%84%E4%BB%B6%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B) 11 - [其它配置](#%E5%85%B6%E5%AE%83%E9%85%8D%E7%BD%AE) 12 - [从viper加载配置](#%E4%BB%8Eviper%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE) 13 - [从配置结构体加载配置](#%E4%BB%8E%E9%85%8D%E7%BD%AE%E7%BB%93%E6%9E%84%E4%BD%93%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE) 14 - [引用配置文件](#%E5%BC%95%E7%94%A8%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6) 15 - [从apollo配置中心加载配置](#%E4%BB%8Eapollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE) 16 - [apollo配置中心命名空间和配置说明](#apollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%92%8C%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E) 17 - [在配置文件中设置从apollo配置中心加载](#%E5%9C%A8%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E8%AE%BE%E7%BD%AE%E4%BB%8Eapollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E5%8A%A0%E8%BD%BD) 18 - [配置观察](#%E9%85%8D%E7%BD%AE%E8%A7%82%E5%AF%9F) 19 - [使用示例](#%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B) 20 - [自动解析泛型结构示例-强烈推荐用法](#%E8%87%AA%E5%8A%A8%E8%A7%A3%E6%9E%90%E6%B3%9B%E5%9E%8B%E7%BB%93%E6%9E%84%E7%A4%BA%E4%BE%8B-%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90%E7%94%A8%E6%B3%95) 21 22 <!-- /TOC --> 23 --- 24 25 # 配置说明 26 27 我们不需要任何配置就能直接跑起来, 当然你也可以使用配置 28 29 + 配置来源优先级: 命令行`-c`指定文件 > WithViper > WithConfig > WithFiles > WithApollo > 默认配置文件 30 + 使用命令 `-t` 来测试你的任何来源的配置是否正确. 31 + 任何来源的配置都会构建为 [viper](https://github.com/spf13/viper) 结构, 然后再反序列化为配置结构体 [core.Config](../core/config.go) 32 33 # 配置加载方式 34 35 ## 从文件加载配置 36 37 + 一般使用yaml作为配置文件, 可以使用命令行 `-c` 手动指定配置文件, 如果有多个配置文件用英文逗号分隔 38 + 也可以使用 `WithFiles` 在代码中指定配置文件 39 + 多个配置文件如果存在同配置分片会智能合并 40 + 如果下面的某个配置文件存在, 会按从上到下的优先级自动加载<b><font color='red'>一个</font></b>配置文件. 41 42 ``` 43 ./configs/default.yaml 44 ./configs/default.yml 45 ./configs/default.toml 46 ./configs/default.json 47 ``` 48 49 通用配置写法如下, 某些特定写法根据`它`的文档为准 50 51 + 插件配置的key为 `plugins.{pluginType}`, pluginType是插件注册的类型值. 52 + 服务配置的key为 `services.{serviceType}`, serviceType是服务注册的类型值. 53 + 组件配置的key为 `components.{componentType}.{componentName}`, componentType是初始化组件时指定的类型值, componentName是获取组件时传入的名字. 54 55 ### 框架配置示例 56 57 以下所有配置字段都是可选的 58 59 ```yaml 60 frame: # 框架配置 61 debug: true # debug标志 62 Name: '' # app名 63 Env: '' # 环境名 64 FreeMemoryInterval: 120000 # 主动清理内存间隔时间(毫秒), <= 0 表示禁用 65 WaitServiceRunTime: 1000 # 默认等待服务启动阶段, 等待时间(毫秒), 如果时间到未收到服务启动成功信号则将服务标记为不稳定状态然后继续开始工作(我们总不能一直等着吧) 66 ServiceUnstableObserveTime: 10000 # 默认服务不稳定观察时间, 等待时间(毫秒), 如果时间到仍未收到服务启动成功信号也将服务标记为启动成功 67 Flags: [] # flag, 注意: flag是忽略大小写的, 示例 ['a', 'B', 'c'] 68 Labels: # 标签, 注意: 标签名是忽略大小写的 69 #Foo: Bar 70 Log: # 日志配置 71 Level: 'debug' # 日志等级, debug, info, warn, error, dpanic, panic, fatal 72 Json: false # 启用json编码器, 输出的每一行日志转为json格式 73 WriteToStream: true # 输出到屏幕 74 WriteToFile: false # 日志是否输出到文件 75 Name: '' # 日志文件名, 末尾会自动附加 .log 后缀 76 AppendPid: false # 是否在日志文件名后附加进程号 77 Path: './log' # 默认日志存放路径 78 FileMaxSize: 32 # 每个日志最大尺寸,单位M 79 FileMaxBackupsNum: 3 # 日志文件最多保存多少个备份, 0表示永久 80 FileMaxDurableTime: 7 # 文件最多保存多长时间,单位天, 0表示永久 81 Compress: false # 是否压缩历史日志 82 TimeFormat: '2006-01-02 15:04:05' # 时间显示格式 83 Color: true # 是否打印彩色日志等级, 只有关闭json编码器才生效 84 CapitalLevel: false # 是否大写日志等级 85 DevelopmentMode: true # 开发者模式, 在开发者模式下日志记录器在写完DPanic消息后程序会感到恐慌 86 ShowFileAndLinenum: true # 显示文件路径和行号 87 ShowFileAndLinenumMinLevel: 'debug' # 最小显示文件路径和行号的等级. 推荐所有等级都打印代码行, 相对于能快速定位问题来说, 这点性能损耗无关紧要 88 MillisDuration: true # 对zap.Duration转为毫秒 89 PrintConfig: true # app初始时是否打印配置 90 ``` 91 92 ### 插件配置示例 93 ```yaml 94 plugins: # 插件配置 95 my_plugin: # 插件类型 96 Foo: Bar # 示例, 不代表真实插件配置情况 97 ``` 98 99 ### 服务配置示例 100 ```yaml 101 services: # 服务配置 102 api: # 服务类型 103 Bind: :8080 # 示例, 不代表真实插件配置情况 104 grpc: # 服务类型 105 Bind: :3000 # 示例, 不代表真实插件配置情况 106 ``` 107 108 ### 组件配置示例 109 110 ```yaml 111 components: # 组件配置 112 cache: # 组件类型 113 cacheName1: # 组件名, 比如提供多个redis客户端连接不同的redis集群 114 CacheDB: memory # 示例, 不代表真实插件配置情况 115 cacheName2: # 组件名, 比如提供多个redis客户端连接不同的redis集群 116 CacheDB: memory # 示例, 不代表真实插件配置情况 117 ``` 118 119 ### 其它配置 120 121 > 除了 frame / plugins / services / components 这几类, 还可以添加自定义配置, 然后使用 `Parse` 方法将配置读取到变量中 122 123 ```yaml 124 myconfig: #自定义分片名 125 Foo: Bar # 示例, 不代表真实情况 126 ``` 127 128 + 更多配置说明阅读源码 [core.Config](../core/config.go) 129 130 ## 从viper加载配置 131 132 > 使用 `WithViper` 设置 [viper](https://github.com/spf13/viper) 结构 133 134 ## 从配置结构体加载配置 135 136 > 使用 `WithConfig` 设置配置结构体 [core.Config](../core/config.go) 137 138 ## 引用配置文件 139 140 + 可以在配置中引用另一个配置文件, 允许使用相对路径, 它相对于程序运行时当前目录. 141 + 被引用的配置文件中不能再添加引用了, 它不会被识别. 142 + 引用的配置文件必须存在 143 144 示例: 145 146 ```yaml 147 include: 148 files: './1.toml,./2.toml' 149 ``` 150 151 ## 从`apollo`配置中心加载配置 152 153 > 使用 `WithApollo` 设置apollo来源和如何加载 154 155 ### `apollo`配置中心命名空间和配置说明 156 157 zapp会将命名空间的名称作为配置顶级key, 该命名空间的配置会作为二级key和其值. 158 159 示例 apollo 配置数据: 160 161 | 命名空间 | field | value | 162 | ---------- | ----- | -------------- | 163 | namespace1 | key1 | value | 164 | namespace1 | key2 | {"foo": "bar"} | 165 166 以上apollo配置数据会被解析为以下配置 167 168 ```yaml 169 namespace1: 170 key1: 'value' 171 key2: '{"foo": "bar"}' 172 ``` 173 174 zapp会将 `applicaiont` 命名空间下的 `frame`,`components`,`plugins`,`services`配置作为配置顶级key, 并将其值按照指定格式解析后赋予其子集(默认是`yaml`格式解析, 需要在apollo配置中设为你需要的格式). 175 176 示例 apollo 配置数据: 177 178 | 命名空间 | field | value | 备注 | 179 | ----------- | -------- | ----------------------------------------- | ---------------------- | 180 | application | frame | {"debug": true, "log": {"level": "info"}} | 会按照指定格式解析其值 | 181 | application | plugins | {"myplugin": {"foo": "bar"}} | 会按照指定格式解析其值 | 182 | application | otherKey | {"debug": true, "log": {"level": "info"}} | 不会解析其值 | 183 184 以上apollo配置数据会被解析为以下配置 185 186 ```yaml 187 frame: 188 debug: true 189 log: 190 level: 'info' 191 plugins: 192 foo: 'bar' 193 application: 194 otherKey: '{"debug": true, "log": {"level": "info"}}' 195 ``` 196 197 ### 在配置文件中设置从`apollo`配置中心加载 198 199 > 文件中添加如下设置, 参考 [config.ApolloConfig](./apollo.go). 从apollo拉取的配置会和文件的配置智能合并, 以apollo配置优先 200 201 最小配置 202 203 ```yaml 204 apollo: 205 Address: "http://127.0.0.1:8080" 206 AppId: "your-appid" 207 ``` 208 209 完整配置 210 211 ```yaml 212 apollo: 213 Address: "http://127.0.0.1:8080" 214 AppId: "your-appid" 215 AccessKey: "" # 验证key, 优先级高于基础认证 216 AuthBasicUser: "" # 基础认证用户名, 可用于nginx的基础认证扩展 217 AuthBasicPassword: "" # 基础认证密码 218 Cluster: "default" # 集群名, 默认default 219 AlwaysLoadFromRemote: false # 总是从远程获取, 在远程加载失败时不会从备份文件加载 220 BackupFile: "./configs/backup.apollo" # 本地备份文件, 留空表示不使用备份 221 ApplicationDataType: "yaml" # application命名空间下key的值的数据类型, 支持yaml,yml,toml,json 222 ApplicationParseKeys: [] # application命名空间下哪些key数据会被解析, 无论如何默认的key(frame/components/plugins/services)会被解析 223 Namespaces: [] # 其他自定义命名空间 224 IgnoreNamespaceNotFound: false # 是否忽略命名空间不存在, 无论如何设置application命名空间必须存在 225 ``` 226 227 # 配置观察 228 229 拥有以下特性 230 231 + <b>一行代码接入配置中心, 解放心智负担</b> 232 + 自动监听配置变更, 每次获取时拿到的是最新的配置数据 233 + 开始watch时会立即从远程获取一次数据, 如果失败会立即打印`Fatal`日志并退出程序(配置有问题程序不应该启动) 234 235 ## 使用示例 236 237 ```go 238 package main 239 240 import ( 241 "go.uber.org/zap" 242 243 "github.com/zly-app/zapp" 244 "github.com/zly-app/zapp/plugin/apollo_provider" 245 ) 246 247 // 可以在定义变量时初始化 248 var MyConfigWatch = zapp.WatchConfigKey("group_name", "key_name") 249 250 func main() { 251 app := zapp.NewApp("test", 252 // 使用apollo配置中心作为配置提供者并设置为默认的配置提供者 253 apollo_provider.WithPlugin(true), 254 ) 255 defer app.Exit() 256 257 // 也可以在这里初始化 258 //MyConfigWatch = zapp.WatchConfigKey("group_name", "key_name") 259 260 // 获取原始数据 261 y1 := MyConfigWatch.GetString() 262 app.Info(y1) // 1 263 264 // 转为 int 值 265 y2 := MyConfigWatch.GetInt() 266 app.Info(y2) // 1 267 268 // 转为 boolean 值 269 y3 := MyConfigWatch.GetBool() 270 app.Info(y3) // true 271 272 // 检查复合预期 273 b1 := MyConfigWatch.Expect("1") 274 b2 := MyConfigWatch.Expect(1) 275 b3 := MyConfigWatch.Expect(true) 276 app.Info(b1, b2, b3) // true, true, true 277 278 // 添加回调函数 279 MyConfigWatch.AddCallback(func(first bool, oldData, newData []byte) { 280 app.Info("回调", 281 zap.Bool("first", first), 282 zap.String("oldData", string(oldData)), 283 zap.String("newData", string(newData)), 284 ) 285 }) 286 287 app.Run() 288 } 289 ``` 290 291 ## 自动解析泛型结构示例-`(强烈推荐用法)` 292 293 通过 `config.WatchKeyStruct` 观察一个key数值变更, 拥有以下额外特性 294 295 + 自动将配置数据作为指定格式解析到一个类型中, 通过`Get`能直接拿到想要的配置数据 296 + 开始watch时会立即对数据结构进行解析, 如果失败会立即打印`Fatal`日志并退出程序(配置有问题程序不应该启动) 297 + 当配置变更时如果解析失败会打印一个`Error`日志并忽略该配置变更(获取到的配置是上一次正确解析的配置数据) 298 + 只有配置变更时才会解析数据, 并不是每次获取数据都解析一次 299 300 ```go 301 package main 302 303 import ( 304 "time" 305 306 "github.com/zly-app/zapp" 307 "github.com/zly-app/zapp/plugin/apollo_provider" 308 ) 309 310 type MyConfig struct { 311 A int `json:"a"` 312 } 313 314 // 可以在定义变量时初始化 315 var MyConfigWatch = zapp.WatchConfigJson[*MyConfig]("group_name", "generic_key") 316 317 func main() { 318 app := zapp.NewApp("test", 319 // 使用apollo配置中心作为配置提供者并设置为默认的配置提供者 320 apollo_provider.WithPlugin(true), 321 ) 322 defer app.Exit() 323 324 // 也可以在这里初始化 325 //MyConfigWatch = zapp.WatchConfigJson[*MyConfig]("group_name", "generic_key") 326 327 // 获取数据 328 for { 329 a := MyConfigWatch.Get() 330 app.Info("数据", a) 331 time.Sleep(time.Second) 332 } 333 } 334 ``` 335 336 [其它示例代码](./watch_example) 337