咱們在實際開發系統的過程中,頗有可能會遇到須要進行系統重構升級的狀況,須要重構的緣由多是以前的設計不合理,致使如今維護起來很是的困難,也有多是如今的業務發展很是迅速,須要進行分庫分表了又或者以前用的是單機的本地的文件存儲,如今須要用到統一的網絡存儲。總而言之,就是當初的系統設計已經不符合如今發展須要了,須要進行重構和升級。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
以爲不錯的話請幫忙收藏點贊~