咱们在实际开发系统的过程中,颇有可能会遇到须要进行系统重构升级的状况,须要重构的缘由多是以前的设计不合理,致使如今维护起来很是的困难,也有多是如今的业务发展很是迅速,须要进行分库分表了又或者以前用的是单机的本地的文件存储,如今须要用到统一的网络存储。总而言之,就是当初的系统设计已经不符合如今发展须要了,须要进行重构和升级。php
而这其中会可能会涉及到代码逻辑的变动,数据存储的变动(如DB或者文件存储等)或者第三方接口的变动。在这样一个新旧的切换过程中,怎么样才能让用户无感知,平稳地进行过渡?segmentfault
有人说可能说能够停服,而后迁数据,迁完后切新逻辑,然而先不说会有一段不可接受的不可用时间,就说在迁移过程当中,咱们如何保证能一次迁移成功呢?再退一步,就算数据迁移成功了,可是若是代码逻辑有漏洞,咱们又该如何快速回退到旧版本呢?这可不仅仅是切回旧代码就行了,要知道这段时间可能产生了新版本的数据,这些新数据可也要迁回旧版本。网络
重构升级系统的过程可能会遇到这么多问题,那咱们有什么办法能够平稳且用户无感知地完成系统升级吗?今天就给你们提供一个通用的系统重构升级的框架。里面不少具体的逻辑得按不一样系统的实际状况来,可是总体思路倒是通用且可靠的。框架
咱们先来模拟一个简单的场景,并看看实际状况中应该如何操做。测试
假设咱们一开始有个users
表存储学生数据,表结构以及一些数据以下:设计
id | name | age |
---|---|---|
1 | 张三 | 18 |
2 | 李四 | 19 |
3 | 王五 | 17 |
后面随着业务发展,咱们须要记录学生的语文成绩,而后咱们在users
表加了score
字段,以下code
id | name | age | score |
---|---|---|---|
1 | 张三 | 18 | 98 |
2 | 李四 | 19 | 76 |
3 | 王五 | 17 | 80 |
过一段时间咱们发现又须要记录数学分数了,后面还可能须要记录英语分数等等。这时候不可能一次次加字段,现有的表设计又极不知足咱们的需求,因此只好对如今的系统进行重构升级了。咱们想用两个表来存数据:接口
students
表开发
id | name | age |
---|---|---|
mark表
get
id | type | user_id | score |
---|---|---|---|
这时候咱们会面临几个问题:
如何来升级呢?
在旧代码的增删改查的地方写好新逻辑和建好新的表,可是一开始线上并不调用新逻辑和写入新表,仅仅在测试环境调用和写入,线上仍调用旧逻辑。如:
if($is_dev){ //新逻辑:如增删改查students表和mark表 }else{ //旧逻辑:如增删改查users表 }
测试新逻辑没问题了,线上同时双写新旧表(包括增删改),如:
//新写入逻辑:如增删改students表和mark表 //旧写入逻辑:如增删改users表 if($is_dev){ //新读取逻辑:如查students表和mark表 }else{ //旧读取逻辑:如查users表 }
users
表的数据迁到students
表和mark
表users
表和students
表、mark
表的数据进行对帐,若是有数据不一致的状况,说明咱们以前双写的时候有遗漏的地方,须要补全,若是没有不一致,说明咱们写入的地方都已经对齐了,如今新旧数据是已经能一直保持一致了,那下面就是切读的地方了。把读的地方改为只读新的,以下
//新写入逻辑:如增删改students表和mark表 //旧写入逻辑:如增删改users表 //新读取逻辑:如查students表和mark表
系统运行一段时间,没发现问题以后把写的改为只写新的,以下
//新写入逻辑:如增删改students表和mark表 //新读取逻辑:如查students表和mark表
完成以后咱们的系统就平稳的完成迁移了。
整个过程可能看起来很繁琐,不要紧,咱们一步一步来分析其必要性。
能够看到,上面的系统升级重构的思路是比较细致的,可是确实是很是平稳,且不须要停服就能完成升级,即便系统很是的复杂,升级重构的逻辑和存储结构大变样也能适用。固然在实际过程当中你们也能够根据实际状况(小系统小改动)进行一些步骤的合并或者缩短期。
转载请注明做者和文章出处
做者: X先生
http://www.javashuo.com/article/p-hufrzoqx-nk.html
以为不错的话请帮忙收藏点赞~