还不会做配置管理?满分工程手把手教你!

还不会做配置管理?满分工程手把手教你!

 关注我,带你学点有用的

前阵子答应了前端群的小朋友,要分享一些企业级前端工程相关的经验,这一拖就拖了快俩月了,再拖估计得掉粉了。

那么今天就开始聊前端工程的话题吧,咱先从配置管理讲起。

这部分非常实用,你要是能帮你的团队把这块事情做漂亮了,那所有人都会对你刮目相看,不管是简历上,还是晋升答辩,都是一块不错的,可聊的内容。

话不多说,直接进入正题。

回忆一下你们的项目,有没有出现类似代码:

php复制代码// 创建一个S3实例
const s3 = new S3({
  // 省略部分参数
  accessKeyId: 'xxxxx',
  secretAccessKey: 'xxxx',
})

这里不用纠结于S3是个什么东西,这不重要,重要的是,类似上面这种,把某些重要参数(比如密钥,IP,人名等)明文写死在代码里的方式。

如果你们项目有类似代码,那么恭喜你,一战成名的机会来了!

这种丑陋的编码方式有一个专业术语:硬编码。顾名思义,就是看完之后让人很僵硬的编码方式。

image.png

哈哈哈,开个玩笑,硬编码的名词解释是这个:

硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中的软件开发实践,与从外部获取数据或在运行时生成数据不同。

硬编码有什么问题呢?大概会有这么几种:

  • 安全问题。敏感信息放代码里,一旦代码开源,或者私有代码被逆向工程,就会产生严重的信息泄漏问题。
  • 变更成本。每次需要调整配置信息,比如换个密钥,换个IP/端口诸如此类的参数,都要重新走发布流程,成本极高。
  • 代码复用。多套部署的情况下,代码几乎无法复用,也难以做个性化部署。

那么稍微正常一点的代码应该长什么样呢?大概是这个样子:

arduino复制代码// 创建一个S3实例
const s3 = new S3({
  // 省略部分参数
  accessKeyId: process.env.AK,
  secretAccessKey: process.env.SK,
})

对应的服务器环境变量:

这一步,把硬编码的密钥,改成从环境变量(process.env)里读取,看起来显得高级多了。这就是最简单的配置剥离,基本上实现了代码可配

是不是看起来好多了?

NO,NO,NO!这才哪儿到哪儿。这种刀耕火种的配置管理方式,问题可太多了:

  • 发布稳定性低。每一套部署都需要独立维护自己的环境变量,发布时候忘记修改某个容器,就会出大问题,所以每次发布都需要有长长的CheckList。
  • 容错率低。完全是字符串式编辑,但凡多个空格,换行啥的,整份配置就都废了。
  • 权限缺失。没有专门针对配置的权限管理,谁都能来改改,改完也没操作记录,万一搞出点什么幺蛾子,该找谁背锅都不知道。
  • 无版本概念。没有版本管理,一旦改出问题,想快速回滚都没办法。

看过我之前文章的人应该多少了解我,沐洒比较喜欢从宏观层面梳理问题的解法,从而更加优雅完备的解决问题。

你可能要急了:沐老师,你就别逼逼了,Talk is Cheap,show me your code

OK,不啰嗦,上架构图!

暂时看不懂没事,我就是先放出来镇场子的,后面会给你一步步讲明白。

首先我们把视线聚焦到架构图的右上角,这里有个Remote Config

Remote Config(远端配置),顾名思义,就是摒弃掉上面我们说的那种刀耕火种的把配置放到环境变量的方式,而采用一个相对成熟的配置管理系统进行管理,类似这样:

(这是腾讯内部的配置系统:七彩石)

一个成熟的配置系统应该长这样,可以非常方便的管理项目的所有配置,分环境,分组,有权限控制,发布审批,日志,版本回滚等功能。

这才是一个现代化的配置管理方式!

如果你公司没有自研的配置中心,也可以选择市面上一些成熟的产品,比如Nacos,Apollo,Spring Cloud Config等等。

当然了,本文的重点不在这,所以咱就不多聊这个。

接着往下看,现在视线挪到架构图底部(CI写配置):

为了保证服务在启动的时候能拿到配置文件,我们需要在CICD的时候就提前把配置从远端拉下来,写入文件,并打包到服务镜像中。

这时候你要问了,从CI到CD可能需要等很久,除了漫长的构建时间之外,可能还有一些更加漫长的审批等待环节,或者等夜深人静的时候延时发布之类的状况,那在此期间如果配置有变更怎么办?我们的配置文件可是提前就打包好了呀!

别急,解决办法这不就来了么!视线回到架构图右上方:

服务部署完毕,正式启动的时候,先执行配置初始化操作(initConfig),从远端配置中心拉取最新的配置到服务器上,并且与旧配置进行融合(Combination),这不就解决了刚刚你担心的配置陈旧的问题了么。

同时,我们需要有一个好习惯,把这份最新的配置存一份文件到服务器本地:

这一步看似多余的备份操作,实则是一次系统稳定性的兜底操作,万一远端配置中心挂了(别人挂不挂咱管不到,咱只能尽可能保证自己不挂),那此时这一份兜底文件就至关重要了!代码实现类似这样:

 
javascript复制代码const fetchRainbowConfig = async () => {
  try {
    // ……省略部分代码
    // 从远端配置中心拉取最新配置
    const config = await rainbowInstance.getGroup();
    const configPath = path.join(__dirname, `../../.env/${RAINBOW_GROUP || 'dev'}`);
    // 写入本地文件
    fs.writeFileSync(configPath, JSON.stringify(config));
    return config;
  } catch (error) {
    console.error('fetch rainbow group config fail!Try to fetch from local');
    // 兜底操作,从本地配置文件读取
    return fetchConfigFromLocal();
  }
}

结束了吗?嗯,做到这一步,其实已经是一个相当不错的工程了,但是我还不满足!这顶多算是一个80分的工程。

咱再继续优化,把视线挪到架构图右下方(Config Watcher):

我们再加上一个配置监听器(Config Watcher),用来做什么呢?

聪明的你应该不难看懂,这个监听器,可以实时监听远端配置的更新,从而实现配置热更新,在某些场景下配置变更不再需要重新发布服务

比如哪天出现一个线上逻辑Bug,需要发一个紧急公告,这时候不用改代码,也不用重新走漫长的CICD流程,只需要在配置系统里加一个公告字段,需要发公告时修改该字段,服务器上的配置监听器就会察觉到更新,立即热更新到内存中。

是不是帅呆了!我愿意打一百分!💯

没错,你做到这一步,这个系统的配置管理模块就算是相当成熟了,既有一定的容灾能力,又有相当的敏捷能力,而且可读性极高,非常利于维护!谁用了不说声好?

好了,一个成熟优秀的企业级配置管理方案,沐洒已经给你倾囊相赠了。

你,学废了吗?

image.png

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值