内容简介:应用系统的配置信息,一般分为两种,一是经常变化的配置则保存到数据库,另外一种则是不常变化的则以配置文件的形式保存。一般而言,应用系统至少有三组运行环境:开发环境、测试环境、生产环境,本文主要探讨在一开始的时候,我针对每个环境配置各自的yaml,在启动的时候根据环境变量读取相应的配置文件,处理代码如下:不同环境的配置文件如下:
巧用viper实现多环境配置
应用系统的配置信息,一般分为两种,一是经常变化的配置则保存到数据库,另外一种则是不常变化的则以配置文件的形式保存。一般而言,应用系统至少有三组运行环境:开发环境、测试环境、生产环境,本文主要探讨在 golang
项目中如何使用viper实现多环境应用配置。如果对viper不了解的可以先去阅读一下官方说明 https://github.com/spf13/viper
。
青铜时代
一开始的时候,我针对每个环境配置各自的yaml,在启动的时候根据环境变量读取相应的配置文件,处理代码如下:
func initConfig() (err error) { env := os.Getenv("GO_ENV") viper.SetConfigName(env) viper.AddConfigPath("./configs") viper.SetConfigType("yml") err = viper.ReadInConfig() return } func main() { err := initConfig() if err != nil { panic(err) } fmt.Println(viper.GetString("db.uri")) fmt.Println(viper.GetString("db.poolSize")) }
不同环境的配置文件如下:
# test app: viper-test db: uri: postgres://tree:mypwd@127.0.0.1:5432/viper-test?connect_timeout=5&sslmode=disable poolSize: 100
# production app: viper-test db: uri: postgres://tree:mypwd@10.1.1.1:5432/viper?connect_timeout=5&sslmode=disable poolSize: 100
由上面的代码可以看出,因为viper读取的配置只有一份,因此需要在每个配置中将所有的配置都一一填写,而不同环境的配置绝大部分都是相同的,只有小部分是不一致。一开始只有不到10个配置项的时候还好维护,后面配置信息越来越多,几十个的时候就是一个深坑了,看到眼都花了,太难管理。
白银时代
各运行环境中的配置90%左右是相同,而剩下的10%才是各环境的差异配置,是否可以将相同的配置以默认值的形式保存,而各环境与默认值不相同的再覆盖呢?查看了一下文档,发现了 viper.SetDefault
的函数,一开始是直接在代码一行行的把默认配置写上,但是这样无法利用yaml的便利,在研究了相关的代码之后,最后调整为如下的处理形式,代码如下:
func initConfig() (err error) { configType := "yml" defaultPath := "./configs" v := viper.New() // 从default中读取默认的配置 v.SetConfigName("default") v.AddConfigPath(defaultPath) v.SetConfigType(configType) err = v.ReadInConfig() if err != nil { return } configs := v.AllSettings() // 将default中的配置全部以默认配置写入 for k, v := range configs { viper.SetDefault(k, v) } env := os.Getenv("GO_ENV") // 根据配置的env读取相应的配置信息 if env != "" { viper.SetConfigName(env) viper.AddConfigPath(defaultPath) viper.SetConfigType(configType) err = viper.ReadInConfig() if err != nil { return } } return }
此函数将 default.yml
的所有配置读取至一个新的viper实例中,再以 SetDefault
将所有配置写入为默认配置,而各环境配置文件只需要配置差异部分,配置如下:
# default app: viper-test db: uri: postgres://tree:mypwd@127.0.0.1:5432/viper-test?connect_timeout=5&sslmode=disable poolSize: 100
# test与default完全一致,为空文件
# production只是数据库连接串不一致,只需要配置此项 db: uri: postgres://tree:mypwd@10.1.1.1:5432/viper?connect_timeout=5&sslmode=disable
通过此调整,不再需要重复的维护相同的配置项,而且也能直观的看出各运行环境的配置差异,减少配置信息的出错概率。
王者时代
因为主要是后端程序应用,程序交付一般都是通过 docker 镜像的形式,配置文件与编译后的应用程序一起打包至镜像中,在多个项目中也使用得挺顺畅。最近有一个项目非运行在docker环境下,因此希望能将配置文件一起打包至应用程序的方式,在了解了几个相关的项目,最终选择了使用 packr 来将配置文件打包,调整之后的代码如下:
func initConfig() (err error) { box := packr.NewBox("./configs") configType := "yml" defaultConfig := box.Bytes("default.yml") v := viper.New() v.SetConfigType(configType) err = v.ReadConfig(bytes.NewReader(defaultConfig)) if err != nil { return } configs := v.AllSettings() // 将default中的配置全部以默认配置写入 for k, v := range configs { viper.SetDefault(k, v) } env := os.Getenv("GO_ENV") // 根据配置的env读取相应的配置信息 if env != "" { envConfig := box.Bytes(env + ".yml") viper.SetConfigType(configType) err = viper.ReadConfig(bytes.NewReader(envConfig)) if err != nil { return } } return }
调整之后,配置文件也编译至程序中,后续可以单执行文件交付,只通过在启动时指定 GO_ENV
则可。
以上所述就是小编给大家介绍的《巧用 viper 实现多环境配置》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 理解SpringBoot自动配置实现
- 小程序页面动态配置实现
- Zookeeper 应用实现-配置中心
- 用 Go 实现配置中心(一)
- 基于zookeeper实现统一配置管理
- React完美实现可配置转盘
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
企业IT架构转型之道:阿里巴巴中台战略思想与架构实战
钟华 / 机械工业出版社 / 2017-4-1 / 79
在当今整个中国社会都处于互联网转型的浪潮中,不管是政府职能单位、业务规模庞大的央企,还是面临最激烈竞争的零售行业都处于一个重要的转折点,这个转折对企业业务模式带来了冲击,当然也给企业的信息中心部门带来了挑战:如何构建IT系统架构更好地满足互联网时代下企业业务发展的需要。阿里巴巴的共享服务理念以及企业级互联网架构建设的思路,给这些企业带来了不少新的思路,这也是我最终决定写这本书的最主要原因。本书从阿......一起来看看 《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》 这本书的介绍吧!