一个合格的CloudNative应用:程序当开源软件编写,应用配置外置
摘要:对于一个合格的CloudNative应用,应该把自己的程序当做开源软件来编写的,不该将数据库连接信息和密码放在代码里,一定要将配置外置。
本文分享自华为云社区《[CloudNative] 企业应用上云实践手记-Cloud Native Phase 3 - 云原生应用AutoConfig》,作者:关耳山石
对于一个合格的CloudNative应用,应该把自己的程序当做开源软件来编写的,不该将数据库连接信息和密码放在代码里,一定要将配置外置。
因此我试着在华为云上落地这套标准,期间尝试了从ServiceStage、CCE、CSE这三个入口进行配置注入,最终实现能够在应用启动时,主动拉取配置,覆盖本地配置文件里的调试配置,并能够在线配置并生效。
打法是:CCE配置启动参数,制定SpringProfiles;配合CSE做应用配置,将资源外置后的配置记录于此,并可以动态更新,最终实现了配置外置的诉求。
另外,通过这次增加的多版本管理,尝试梳理了一下ServiceStage的组件、CCE的workload、CSE的应用和微服务之间,错综复杂的概念之间的关系,个人浅见,欢迎指正:
1. 初始化配置
在系统初始化的时候,不可能一点配置都没有,所以保留一些基础配置在配置文件里是有必要的。配置外置并不意味着100%的配置都要外置,而是把外部依赖资源的配置,特别是容易变化配置外置。
1.1 启用Bootstrap和Spring profile
在代码层面,首先要进行基础配置。先看代码结构,这里除了最基本的application.yaml,增加了bootstrap.yaml和*-dev.yml等带后缀的文件。
介绍一下原理:
- 首先介绍Bootstrap Application Context:
它是Spring Cloud Context的父Context,所以从外部配置源里加载配置一般从这里来,且优先级高于其他一切配置文件。于是,我们也利用这个能力,借助CSE的微服务配置中心能力,进行Spring的外部参数写入。
- 然后介绍Spring profiles:
为了把通用配置和环境相关的配置区分开,比如DEV环境没有AK/SK认证,而线上环境都有认证,这种配置项上的区别,引入了Spring profiles的概念,当Springboot启动的时候,会根据profiles.active参数判断应该启用那个环境配置
PS:参考SpringCloud官方解释
另外,就是哪些配置应该放在配置文件里,理论上除了最基础的配置,在启动时使用的,其余的配置都可以放在CSE的微服务配置中心里,而不必在本地配置文件里存在,另外就是本地配置里存在的,也可以通过二次设置在微服务的配置中心里,进行覆盖,比如数据库连接池的大小,而不需要修改代码,至于改完以后,要不要重启,那就得看生效的逻辑了。
1.2 引入CSE配置中心
CSE配置中心引入,需要先引入依赖包,然后在bootstrap.yaml中配置CSE配置中心的地址、认证信息等。
这里可以参考官方文档,主要关注bootstrap.yaml的配置参数:使用分布式配置中心
补充:获取spring-cloud-starter-huawei-config的版本
参考地址:huaweicloud/spring-cloud-huawei
可以参考现有的SpringCloud基线版本,选择SpringCloud-Huawei的版本
补充:关于配置中心的优先级
微服务引擎提供了分层次的配置机制。按照优先级从高到低,分为:
- 配置中心(动态配置)
- Java System Property(-D参数)
- 环境变量
- 配置文件
参考官方文档:配置微服务
2. 本地CSE配置中心能力验证
前提条件,本地得安装一个Local-CSE并启动,这部分参考云上DevOps:2.1-本地环境准备
2.1 配置application.yaml和bootstrap.yml
原始文件可以参考Github的Demo,配置文件入口,我这里进行了修改,因为bootstrap.yaml优先级高于application.yaml,参数只要在bootstrap.yaml中出现过,就不会使用application.yaml中的配置了。
上代码,application.yaml,可以看到配置很少,因为大部分bootstrap.yml中已经包含,就都去掉了
这是bootstrap.yml,注意这里的spring.application.name、spring.cloud.servicecomb.discovery.appName和spring.cloud.servicecomb.discovery.version会组成一个微服务私有的参数作用域,这里的优先级高于全局作用域application。特别注意,云上的CSE环境,除了上面提到的,还需要增加server.env参数。另外,server.env有四个参数可以选development、testing、acceptance、production
关于如上参数的定义,参考官方文档:使用分布式注册中心和官方文档:使用分布式配置中心。
2.2 准备验证代码
直接上代码
2.3 静态配置能力
为了验证CSE配置中心的参数,是否能覆盖application.yaml中的参数配置,我选了一个很特别的参数:spring.datasource.password,如果能够覆盖成功,那么启动后,创建数据库连接池一定会报错。
- 首先,打开本地CSE配置中心,地址为:http://localhost:30106/#/cse/services/config,创建一个配置项,作用域选VodMgrService@CabgOne#1.0.0,关于application的作用域后面再解释。
- 重启本地微服务,启动后创建数据库连接池就报错了,符合预期。
结论:CSE配置中心的参数,能够覆盖application.yaml中的参数配置
2.4 动态配置能力
为了验证CSE配置中心的参数动态生效,需要使用注解@RefreshScope,同时也引入ConfigRefreshEvent来监听事件变化,这样就会得到一个效果,对于动态生效的参数,可能需要一些重建或刷新,比如连接池、缓存、Client等。
- 首先,增加一个配置项config.value
- 然后很快可以看到后台日志打印出来,包括自己的监听器,也响应了日志
- 查看一下数据,已经响应为TryMe
- 具体的配置,在后台是轮询的,响应周期配置参数为cloud.servicecomb.config.watch.delay,目前是10秒一次
- 修改一下配置,为TryMeAgain
- 再看后台日志,有新的触发器发生
- 再次请求API,数据已经更新
- 再深入去看,这里的getChange()返回是一个Set<String>,因此可以针对特定的参数做文章。
结论:本地CSE配置中心的参数能够动态刷新,并开放了ConfigRefreshEvent,以扩展配置更新后的业务动作。
2.5 配置的作用域限制
目前CSE的配置中心提供两级作用域限制,一个是全域,一个是私域,即微服务内部(不同版本有区分)。
- 增加一个作用域为application的全域参数,一个作用域为VodMgrService@CabgOne#1.0.0的私域同名参数
- 验证一下,生效的作用域是VodMgrService@CabgOne#1.0.0
- 删除私域参数后,生效的作用域是application
结论:本地CSE配置中心的全域配置的优先级,低于微服务内部配置,即私域配置可以覆盖全域配置。
3. 云上配合外置落地
3.1 代码提交并自动打包推送SWR
代码提交,推送到CodeHub上,流水线在CloudPipeline自动驱动起来,开始执行,打包、制作镜像、推送SWR,并且展开了代码质量检查。这些得益于前面的WIKI:Phase2 - 云上DevOps
3.2 CCE启动参数配置
由于ServiceStage的自动部署能力还不满足,所以手工将DockerImage升级到环境上,这里直接使用CCE进行操作,原因在题记里介绍了,ServiceStage的参数配置不太好用
3.2.1 利用CCE的容器启动命令写入参数
- 选择升级版本,点高级配置,CCE的核心配置入口都在这里了
- 在启动时,注入最核心的一个参数-Dspring.profiles.active=uat
- 此处的命令是Docker启动是的ENTRYPOINT,下面那个是CMD,会覆盖Dockerfile里的命令
- 点击右下角的提交,会看到实例列表中已经有一个新的pod在启动
- 回到AOM服务,查看日志,会发现The following profiles are active: uat,符合预期
3.3 CCE环境变量配置
3.3.1 利用CCE的环境变量写入参数
- 首先回退上面那一步的配置,进入高级设置->环境变量
- 增加环境变量JAVA_TOOL_OPTIONS,值设置为-Dspring.profiles.active=uat
- 提交以后查看日志,符合预期
至于为啥JAVA_TOOL_OPTIONS能用,因为JVM原生就包含这个参数,可以用来在启动时写入配置,可以参考Oracle的官方文档
3.4 CCE配置中心
3.4.1 利用CCE的配置中心 + 环境变量写入参数
CCE的配置中心包含了两个大类,配置项ConfigMap和秘钥Secret,前面介绍的CCE环境变量,支持从配置中心导入参数,比如我可以在ConfigMap里写入这个参数,然后在CCE的环境变量中引入。
- 首先创建一个配置项,这里的配置项是按照集群、命名空间区分的
- 然后创建一套配置项,输入一套KV
- 回到CCE升级的步骤,修改环境变量,增加一项配置项写入的变量,可以选到刚才输入的KEY,就不用输入VALUE了
然后再看看秘钥,玩儿法类似,但是有一点很“有趣”:这里的秘钥是要主动用BASE64转码过才能保存,不过在使用的时候,会解密的,因此不必关心转码回来的问题。
3.4.2 利用CCE的配置中心 + 数据存储写入参数
无论是配置项ConfigMap还是秘钥Secret,都可以支持利用CCE的数据存储挂载能力写入参数到容器里,简单理解,就是会自动帮你把配置下载到一个容器的存储位置上,文件名是KEY,内容是VALUE,可以在代码里读取这个配置。
配置方式很简单,选择配置项,然后写一个挂载目录即可
3.5 云上CSE配置中心
这里是另一个核心,线下验证过,云上的CSE类似,但是配置模型更复杂,增加了server.env维度,并且全域和私域参数配置位置不一样。
- 首先,从ServiceStage->微服务CSE->配置管理,进入全域配置页面,选择环境为yaml里配置的server.env参数
返回结果为,生效
PS:如果这里不选环境,则参数无法读取,即环境为空也是一类环境,不同环境之间隔离
- 然后,从ServiceStage->微服务CSE->微服务目录,进入私域页面
进而选择动态配置,在配置作用域时,选择不带version的,环境是固定值,
返回结果为,生效
- 同样的页面下,在配置作用域时,选择带version的,
返回结果为,生效
总结:云上CSE配置中心参数加载优先级
- P1:微服务私域,带Version
- P2:微服务私域,无Version
- P3:全域,带环境
其余参数都不生效,包括全域无环境、全域不同环境、微服务私域不同Version
总结
综上,基于华为云ServiceStage、CCE、CSE的配置外置能力,可以支撑微服务在不同环境中灵活部署,而无需修改代码。目前的总结打法是:
- 利用CCE的容器启动参数,或环境变量,写入profiles.active参数
- 利用CSE的配置中心,写入业务参数,如MySQL连接串、连接池配置、GES引擎地址、VOD服务Endpoint地址等
点击关注,第一时间了解华为云新鲜技术~
一个合格的CloudNative应用:程序当开源软件编写,应用配置外置相关推荐
- 一个合格的web前端程序员要学会哪些技能?
想要成为一名合格的web前端程序猿,要学习的东西有很多,那么web前端要学会哪些技能呢?来看看下面的详细介绍就知道了. 一个合格的web前端程序员要学会哪些技能?想从事web前端开发,只会HTML.C ...
- 如何实现一个直播平台的相关基础及开源软件推荐
如何实现一个直播平台的相关基础及开源软件推荐 首先我们要大致知道一个直播系统核心的构成要件主要是三部分: 采集--主播使用 OBS 之类的软件来录制视频,并能够将数据发向服务器 转播--服务器使用 S ...
- 一个合格程序员的标准
一个合格程序员的标准 2009年02月21日 星期六 01:37 A.M. 假设你是一名软件专业毕业的本科学子,如何在工作中修炼成为一名有较高职业水准的程序员呢,本文试图总结作者从事15年软件开发工作 ...
- 一个合格程序员的标准(转)
假设你是一名软件专业毕业的本科学子,如何在工作中修炼成为一名有较高职业水准的程序员呢,本文试图总结作者从事15年软件开发工作的感想,希望对有志成为职业程序员的人有所帮助,并借此机会感谢原昆明工学院计算 ...
- 独家 | 建立软件的经济学分析框架,浅议开源软件的经济学特性(附图解)
人类社会正在加速数字化.一个显而易见的事实是,人们生活.工作的方方面面都离不开各种各样的软件.不久以前,人们还不知道什么是软件:从今往后,软件正在吞噬整个世界[https://a16z.com/201 ...
- 开源软件能够赚到钱吗
中科红旗的总裁赵晓亮曾经用一个关于饮水的比喻来解释开源软件企业是如何赚钱的,大意是人每天都要喝大量的水,但饮水是在不同的环境下.不同的条件下进行的.虽然原料都是水,但性质已经发生了改变.而且水的加工程 ...
- 开源软件新时代:55个经典开源Wind…
开源软件新时代:55个经典开源Windows工具 开放源代码软件已经成为一个时髦的名词,这里有两个有力的证据:Firefox浏览器的下载人次超过了2500万:同时,基于Linux的Web服务器也占据了 ...
- 《开源软件开发导论》作业1
关于开源的五个问题 作业要求 五个问题 1.开源的三个阶段具体含义是什么? 2.开源的版权如何使用? 3.一个开源项目如何得以正常运行? 4.开源如何保证安全? 5.对我们学生来说开源应该算什么? 作 ...
- 开源软件总体拥有成本指南
Guide to the Total Cost of Ownership of Open-Source Software 开源软件总体拥有成本指南 Tuesday May 10, 2022 by Pe ...
最新文章
- Git中的工作区(Working Directory)、暂存区(stage)和历史记录区(history)
- 小分子溶液当硬盘!布朗大学逆天研究:用代谢分子存储照片,准确率达99%
- python 列表推导式 - 列表字典取value
- JAVA中循环删除集合中元素的方法总结
- python自带超参调优包
- php redis.h,swoole安装hredis支持导致php不能加载swoole扩展
- JAVA类(手机充电、放音乐示例)
- 打造人脉不如打造自己
- SAP BASIS 工作台请求和定制请求的区别
- 屏保延迟启用密码保护
- 在ASP.NET应用启动的时候初始化的几种方法
- dom运行java中文错误,java – org.w3c.dom.DOMException:WRONG_DOCUMENT_ERR:一个节点用于不同于创建它的文档中的文档...
- JNI/NDK入门指南之JavaVM和JNIEnv
- IM 产品设计思考(3) - 呼叫中心及IVR
- lamp兄弟连 mysql_LAMP兄弟连原创视频教程(笔记五--文件上传下载,mysqli对象,session,cookie,date函数)...
- 【合同】产品设计:ID与MD设计合同模板
- c语言源代码三角函数大全,【C语言及程序设计】项目2-9-3:编制三角函数表
- 基于Pytorch实现GAT(图注意力网络)
- 【不想读paper的时候看看】阅读文献?
- powerdesign java,PowerDesigner设计数据库表
热门文章
- Bootstrap 缩略图
- CSS3 多列布局列的填充方式column-fill属性
- es6 next()、throw()、return() 的共同点
- es6 Symbol概述
- 医学专用计算机证,问一下,医学生考计算机2级证和心理咨询师证有用吗
- iphone降级_ios14.2怎么降级到14.1_ios14.2降级14.1方法一览
- 类和对象(2)—— 类的封装和访问控制
- 预备作业03 20162316刘诚昊
- Html中Select的增删改查排序,和jQuery中的常用功能
- zoj3715 Kindergarten Election