View on GitHub

modularization-examples

代码防腐实用技术

考虑以下三种做法:

我把这三种做法都归纳为 Multi Variant,多个变种。它们都是在不改变进程的情况下,通过配置等方式更灵活地进行装配组合。 这样发布和上线就可以解开为两个操作了。上线就是上线,改变进程里的可执行代码。 上线可以不把 Feature Flag 打开,而是保持原有的行为。除非 Feature Flag 本身实现得有bug,上线过程的风险就小了很多。 然后再慢慢地打开 Feature Flag 的流量开关。

Feature Flag 未必一定是用 if/else 实现的,它可以是基于插件机制来实现的。 根据不同的 Feature Flag 的配置信息,选择执行同一个插件的不同版本。 其实质是运行时的插件动态装配。把发布从进程粒度,降低到插件的粒度。

Feature Flag 虽然好用,但是仍然要先完成上线。从 Feedback 周期来说仍然不够理想。 如何在上线之前就测试好呢?本地搭建一个完整的环境困难重重,不仅仅可能笔记本性能不够,而且还有一大堆的数据配置依赖。 理想情况当然是可以把业务拆成更小的部分,只做一部分的集成就能完成测试。 比如说一个app里包括了打车和外卖,那需要打车和外卖都打包进去吗?显然可以只跑打车的代码嘛。 但是部分集成不是免费的,每添加一种部分集成的跑法,就给代码增加了一个运行模式,是需要额外维护的东西。 当团队比较多的时候,只有维护生产环境是大家共同的目标,你自己搞出来的一个部分集成的环境,未必能够得到其他人的认同和资源支持。

所以 Test in Production 才会逐渐火起来,因为只有 Production 才是唯一公认必须保持稳定的环境。 在自己的笔记本上只启动自己修改了代码的进程,才更符合高效分工的原则。 根据概率论,一个系统的稳定性是其构成模块稳定性的乘积。 如果要本地搭建一个完整的集群,必然是一个很不稳定的东西。 在有了多租户的前提下,Test in Production 仅仅需要解决部分替换进程这个问题。 通过在 Http Header 中附加路由信息(例如 Istio Request Routing), 是可以实现一个集群中其他进程都用生产环境,但是你修改的进程替换成你本地启动的。

我们总结一下

理想的快 Feedback 工作环境里,上线应该是每个小时都发车,随意可以搭车的。 多个团队的Git仓库其实是跑在一个进程里。 每个团队通过 Feature Flag 来做自己的灰度测试,出了问题可以一键回滚。 一次可以只变更一个租户,确保不出大面积故障。开发者不需要费心维护自己私有的开发环境,而是直接 Test in Production。 需要全链路压测的时候,创建一个新租户,放心大胆地随便随便测。