Spring 提供了一套代码多环境运行的基本解决方案。
通过application-xxx.yml,辅助启动时指定xxx环境,使得不同环境可以拥有独立的配置内容。 例如
java -jar xxx.jar --spring.profiles.active=xxx 复制代码
目前我们有3套研发环境,差不多9套生产环境。据我推测,生产环境的数量还会不断增加。
让我花点时间来解释一下哪里弄出来这么多生产环境:snowman:️
所以最后我们的配置文件变成了这样 :information_desk_person:♂️
你大概觉得好像还能接受,毕竟生产环境不是天天增加,虽然看起来确实丑丑的。
真棒,你是个乐观的人,和我一样!
我们拆了差不多30个左右的服务,现在每个服务都要维护12个application-xxx.yml的配置文件。
很好!我们现在要维护差不多30*12=360个配置文件了!(其实还有360个logback配置文件 ♂️) 随着服务数量和环境数量的增加,配置文件会以n^2的速度增加。
我们的运维大兄弟根本不管研发死活,他反正是快活不下去了。
如此多的配置文件真的让人心力交瘁。每次新增一套环境,运维大兄弟都要跟这30个服务的owner详细确认每个配置项的值,比如数据库地址啦,redis端口啦,是否启用本地存储啦……(每个配置文件平均有10个左右的配置项,而大部分配置项都是服务owner定义的,运维大兄弟并不知道是什么意思)
万一有个公用的配置需要改动(比如数据库地址需要由公网地址改成内网地址),运维大兄弟又要跪求这30个服务的owner,让他们把每个服务的配置文件都改一遍。
每次新增环境这种修改可能反复多次。
我觉得运维大兄弟已经精神分裂了,服务owner们也心力交瘁。
这一切真是妙不可言 :full_moon_with_face:
我们终于忍无可忍了。
仔细想想,每套环境变化的配置就那几个,数据库,redis,elastic,域名。其他配置基本是不变的。
而这些变化的东西,服务owner可以不用知道,只要运维大兄弟清楚就可以了!
于是,我们尝试做了两层配置文件:将所有配置,根据服务owner与运维大兄弟的知识领域不同,切分到了2个不同的配置文件中。
服务相关的配置,比如是否启用redis缓存,文件存储路径,是否启用邮件通知等等。这个配置文件的特点,就是只有服务owner知道这些配置是什么意思,运维大兄弟并不清楚里面的配置项的含义。通常这个配置文件的内容无需根据不同环境区分。比如某个服务在A环境没有启用邮件通知,那么这个服务在各个环境都不会启用邮件通知。
这个配置文件由服务owner自己维护在application.yml默认配置文件中。
资源相关配置,比如数据库地址,redis地址,端口,es地址,oss地址等等。 这个配置文件的配置项非常固定(因为用到的资源就那么几个)。其特点是只有运维大兄弟知道怎么配置,配置值随着不同环境改变。
服务配置文件直接定义在application.yml中,这个默认配置文件通过引用固定的 资源配置变量 (数据库地址,redis地址端口等等),从而和资源配置文件对接。
举个例子,所有30多个服务都可以在application.yml中通过
${db.host} 复制代码
获取数据库地址。
比如panda服务可以这样配置自己的数据库地址:
spring.database.url=${db.host}/panda&encoding=utf8 复制代码
我们做了什么?现在每个服务都有了2类配置文件,看起来配置文件数量变得更多了!
不过仔细想想,其中服务配置文件是无需跟随环境变更,只有资源配置文件会随环境改变。
让我们看看目前为止,发生了哪些变化。
由于各个服务引用的资源地址都是相同的(比如数据库host,redis host等等),每次新增环境时,运维大兄弟需要为新环境准备一个资源配置文件,然后把这个文件发给所有服务owner,要求他们把这个资源配置文件加入到自己服务的代码中。在这个配置文件中,运维大兄弟只要维护一些基本的数据库地址,redis地址等资源相关配置就可以了,这些概念都是他熟知的。
对于服务owner而言,变化似乎更加明显。新增环境时,运维大兄弟不会不停地和自己沟通每个配置的值是什么了,而是直接丢过来一份资源配置文件,类似application-resource-dev.yml,要求每个服务owner打包在程序里。服务owner甚至不需要关心里面放了哪些东西。
运维大兄弟启动服务时,会指定服务所对应的资源配置文件,比如这样
java -jar xxx.jar --spring.profiles.active=resource-dev 复制代码
这30多个服务引用的资源配置文件内容都是一样的,那么能否把这30个相同的配置文件从代码里抽离出来呢?
我们终于想到了nacos。
这是入沟系列不是入坑系列,nacos基本概念就不讲了。
我们现在要做的是,把这30多个服务共用的资源配置文件,维护到nacos配置中心,并让这些服务指向nacos就可以了!这非常简单!
让我们看看引入nacos后,发生了什么变化。
每次新增环境时,运维大兄弟需要在nacos中,维护一个资源配置文件,比如resource-dev.yml. 在资源文件中定义各类资源的主要信息,而无需再和服务owner有任何交流。甚至未来新增服务,运维大兄弟也可以不用关心,因为每个服务都会按照约定来读取资源配置。
启动服务时,运维大兄弟只要在启动命令中指明启动配置文件的名字,服务就会自动去nacos读取对应资源配置文件的值,例如
java -jar xxx.jar --spring.profiles.active=resource-dev 复制代码
对服务owner而言就更加美妙了,新增环境不需要他们做任!何!事!情!
他们只需要在application.yml中,按约定读取资源配置的值,并使应用启动时连接到nacos配置中心就可以了。而这些只是一次性的工作!一劳永逸!新增环境再也不需要各个服务owner做任何事情了。这一切简直太棒了!
每个的服务配置文件变成了这样
#技术管理/环境管理 #Java开发从入坑到入沟