作者以飞机更换引擎为例来向我们展示了一个,如何给针对一个飞速发展的系统进行大幅度的改造,可以通过将All-in-one的架构改造成微服务架构,来尽可能减少或消除停服的时间。
一般重构的分类分为3种:
- 彻底重新做,直接从前到后抛弃老系统。
- 大规模重构,保留对用户的这层皮,后面从服务到数据全部替换
- 小规模重构,保留对用户的这层皮以及数据结构,逐一替换核心逻辑到微服务
在更换引擎方案选择和设计的时候需要考虑到以下几个现实的情况:
①业务需要发展(由于新需求的开发时间不定性)最好在重构之前对新增业务有一条界限,先完成新系统这一需求的部署、检测,修复Bug等一系列操作,使其达到该需求下的新系统的稳定,然后再将新的精力放到新需求的开发。
②数据需要迁移(由于我们更换的是一架正在使用的飞机,我们需要在更改系统,添加新功能的时候,对旧数据进行迁移),我们需要做:
· 准备迁移脚本
·· 准备缓存预热脚本
··· 使用既有的数据来测试这2个脚本,然后观察新系统的运行情况
···· 做反向数据迁移的脚本,我们要考虑到切换到新系统后运行不流畅需要整体回滚的情况,这个时候我们需要把数据从新的数据库迁移回老的数据库。
以上的迁移方式免不了需要短暂时间的系统停机,两个脚本的执行和验证需要一段时间,如果想要减少停机时间的话可以采用两段走的方式,先执行迁移脚本,再执行缓存预热脚本,或者让业务同事走两套系统进行双写,这种方案大大增加复杂度,但是可以换来几乎0停机的时间,但是一般的系统,不会考虑这种做法,因为一般的我们重构时,不会想去更改底层数据库,这样会增加复杂性,但是,由于很多时候我们的底层数据库并不是很灵活,如果不切换到新的数据库,即使搞成了微服务架构数据还是揉在一起,只是形态上是微服务,底层还是乱七八糟,这堆业务代码最终还是要进行一次重构。
③最好没有停机让用户感知
我们通常希望,添加新需求时,对系统的更改不会影响用户的使用,最好能让用户没有感知,我们思考以长得一模一样面子的新老两个系统,两套系统都在线上运行,通过我们自己底层调用的更改,我们可以在内部对新系统进行充分测试,还可以比较同样的业务流程在数据呈现上是否有差异,但往往现实中,我们常常会依赖各种第三方数据,我们依赖的第三方会受到我们重构的影响、或是我们就是在切换依赖方的话,是否停机非自己可以掌控的,这个时候我们能做的是,让网站进行部分功能的停机而不是整体停机,用户可以以只读形式使用网站的所有功能,但是不能做写入操作,待三方系统切换完成后切换到新系统了才能使用所有功能,这样用户也会有安全感。
④万一迁移失败怎么办
我们需要做到的是隔离清楚,让新老系统彻底独立,内部要进行彻底的隔离,对于三方的数据,我们也要考虑到数据在边缘节点和用户端缓存的情况,在设计方案的时候就要考虑到切换后回退的可能性,尽可能让两套系统使用独立的数据不要产生数据覆盖的情况造成污染。
当然更换架构时,最重要的是得到产品方面的配合对需求做好锁定、在开发过程中对新系统做好充分测试减少上线后修Bug的工作量、对迁移方案以及回滚方案做好自动化的脚本以及充分的验证。