配置版本化是怎么实现的

在阿布去年进行召回引擎开发时,涉及到了一个远程配置的拉取功能,为了 mvp 流程的尽快上线,当时使用了最易实现的单版本模式,就是把 场景、渠道、索引、关联信息 等配置存储到 mysql 表中,且只有实时的一份数据。

关于动态配置的获取,有两种思路,1、配置实时拉取,即使用时进行实时的配置查询;2、配置的动态下发,即配置发生变更时注入本地缓存,使用时查询缓存。各位读者朋友,你们觉得应该使用哪一种思路呢?

单版本模式的缺点是显而易见的,随着阿布开发的召回引擎越来越重要,承接了越来越高的流量,当老板知道当前引擎强依赖的配置竟然没有备份,且无法回滚时,是非常震惊的(虽然阿布早就跟老板说过这一点),责令阿布尽快开发配置的版本能力,实现配置的多版本、可回滚、可追溯等功能。

激烈的讨论

作为一个组内的小卡拉米,阿布当然要把组内的大佬发动起来,群策群力,听取大家的方案,同时也把自己的方案摆出来,让大家批斗一下。大家也都很给力,讨论的过程异常激烈,会议室的门都要飞起来了(怀念当时组内的氛围,后面阿布换组后,再也没这种盛况了)。为了本文的篇幅,阿布就只简单总结一下各位大佬的方案,讨论的过程就略过了。

阿磊的方案

阿磊首先是从发布的角度来考虑的。对于召回引擎来说,修改线上配置的时间点一般是需求上线,而需求上线的流程首先是新建 release 分支,然后经过预发、灰度、生产环节,最后 release 分支代码合并至 master,需求完成发布。因此,阿磊认为应该将配置与分支进行绑定,即每一个分支对应 1~n 个版本。

配置更新时,获取当前的 release 分支,单独的配置版本记录表将 分支-配置版本号-配置记录ID 关联关系存储下来,配置快照表将当前配置存储为快照进行归档。

配置获取时,首先查询当前的 release 分支,再从配置版本记录表中查询配置记录ID,再根据配置的记录ID去快照表中获取配置数据。

阿磊是组内公认的架构师,思考问题比较全面,但是大家认为方案的复杂度比较高,与发布分支的关联关系让大家理解比较困难。

阿布的方案

阿布认为当前召回引擎已经承接了非常大的流量,应该进行最小改动。反对新增快照表进行不同版本配置的存储,而是应该采用配置的染色法,在当前的配置表中都新增一个版本字段。

配置更新时,判断当前的配置版本数量,如果只有一个版本,那么进行配置的新增。如果有两个版本,那么移除最老的版本,再进行配置的新增。

配置获取时,默认进行最新版本配置的获取,当配置需要回滚,整体移除新版本配置,下发老版本配置。

大家都认为阿布的方案脱裤子放屁,实际上也是快照的方案,将快照数据与基础的配置数据揉到一块,让数据更加混乱,而且只能进行两个版本的切换,只具有着有限的追溯与回滚能力。大家都笑话起了阿布,空气中充满了快活的空气。

最终方案

经过了数次的方案讨论会议,最终敲定了比较简单,符合当前业务需求的方案。

快照表是必要的,由于召回引擎的单个版本配置并不是非常大,因此预计在较长时间内,单张表完全可以承载记录配置快照的诉求。同时新增配置基础表,表中的 status 标识配置的预发、灰度、生产状态,valid 字段标识配置是否有效。配置基础表与快照表通过配置ID进行关联。

配置更新时,将全量配置新增到配置的快照表中,基础表中新增该配置的一条记录,同时根据该配置更新时约定的状态,例如,本配置为灰度配置,那么就将配置基础表中该配置的 status 置为灰度。需要注意的是,相同状态的配置只能存在一个,当配置发生更新时,就会根据当前配置的状态,将其它同状态的配置置为无效。

注意,定义配置的更新动作为:开发同学完成了本次需求全部配置的修改,然后触发这一揽子更新。

配置获取时,需要根据不同容器节点的状态进行下发,如果当前容器节点处于灰度状态,那么就去寻找灰度配置下发,如果处于生产状态,就会寻找生产状态的配置进行下发。

配置回滚时,拉取历史配置并选择下发,同时将其它同状态的配置置为无效。

预发/灰度验证时,将新增的配置置为预发/灰度状态,配置下发完成后,预发/灰度容器就获取到了新的配置,而且不影响生产。

当发布从灰度切到生产,配置的状态也需要从灰度变更为生产,确保启动后的生产容器能够读到最新的配置。

结语

在阿布的辛苦劳累挑灯夜战下,配置版本化功能如期上线了,支持配置的多版本、多状态,支持了可追溯、可回滚能力,无论是预发、灰度或是单个节点,都支持配置的下发验证。老板很高兴很满意,对阿布说:"多亏了阿磊啊,你当时的方案就是个乐子!"。

相关推荐
周末程序猿5 分钟前
Linux高性能网络编程十谈|C++11实现22种高并发模型
后端·面试
ZHOU_WUYI12 分钟前
Flask与Celery 项目应用(shared_task使用)
后端·python·flask
冒泡的肥皂1 小时前
强大的ANTLR4语法解析器入门demo
后端·搜索引擎·编程语言
IT_陈寒1 小时前
Element Plus 2.10.0 重磅发布!新增Splitter组件
前端·人工智能·后端
有梦想的攻城狮2 小时前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener
Java水解2 小时前
MySQL DQL全面解析:从入门到精通
后端·mysql
Aurora_NeAr2 小时前
Apache Spark详解
大数据·后端·spark
程序员岳焱2 小时前
Java 程序员成长记(二):菜鸟入职之 MyBatis XML「陷阱」
java·后端·程序员
hello早上好2 小时前
BeanFactory 实现
后端·spring·架构
我命由我123452 小时前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea