上線穩定性如何保證?開關程式設計很有用

架構擺渡人 發表於 2021-11-27

大家好,我是架構擺渡人。這是實踐經驗系列的第一篇文章,這個系列會給大家分享很多在實際工作中有用的經驗,如果有收穫,還請分享給更多的朋友。

在日常工作中,無論是一週一個迭代,還是兩週一個迭代,都避免不了上線的環節。唯一的區別就是上線的頻次不同而已。那麼我們如何保證在這麼高頻次的發版裡面同時保證穩定性呢

答案就是開關程式設計,所謂的開關程式設計其實就是加個if判斷,但是可以動態去調整if裡面的值,能夠隨時控制邏輯的走向。開關需要自己編寫,自己控制,動態調整值則可以藉助於配置中心,改變後實時重新整理。

案例一:舊功能裡面加新邏輯

假設你要對訂單詳情頁面做調整,增加一部分內容或者修改老的邏輯。正常的做法就是直接改掉老邏輯,然後測試,然後上線。

如果測試覆蓋了所有的場景,上線後也不會有任何問題。就怕有某些場景遺漏了,導致在測試環境中沒有發現的問題,一上線就出問題了。此時你的邏輯已經是最新的了,唯一的解決辦法就是回滾應用到之前的版本,回滾是下下策,不到萬不得已千萬不要做,因為回滾可能帶來更嚴重的問題。

這次釋出所有的新功能都丟了

如果執行回滾操作,也就意味著這次釋出要上的新功能都沒有了,如果你的服務拆的夠細,可能影響面會稍微小點。

假設服務端回滾了,如果此時客戶端已經發布,像H5還好說,也可以回滾,像APP如果使用者已經更新到最新版本了,你服務端回滾了,使用者一用到新功能就直接報錯了。所以請慎重回滾。

所以此時你可能沒辦法回滾,只能快馬加鞭改Bug,然後緊急釋出進行修復,玩的就是心跳啊。

開關的作用來啦

在改動舊邏輯的時候,不要直接改,可以在內部採用分版本的方式進行調整。把之前的邏輯定位V1,要改的邏輯定位V2,然後通過開關去切換。

虛擬碼如下:

boolean switch = false;
if (switch) {
  // 走新改的邏輯
} else {
  // 走舊邏輯
}

通過增加開關來保證穩定性,預設開關是關閉的,上線後還是走舊邏輯,無任何影響。釋出完成後再將開關開啟,此時走新邏輯。如果新邏輯出現了Bug,立馬將開關關閉走舊邏輯,不用回滾整個服務,是不是很穩。

此時,又有同學抬槓了,你這雖然能快速回滾,如果流量大的話影響還是很大啊。是的,如果要保證最小的影響,那麼就需要結合灰度來實現了,這塊後面再給大家介紹如何去做。

案例二:大促前的功能降級

對於很多電商公司來說,大促必不可少。每年都有像週年慶,618,雙十一,雙十二之類的大促期。

大促的時候,流量也是最高的時候。此時最重要的就是P0級別的核心鏈路,其他不是很重要的可以降級,以免影響到主鏈路的功能。

比如訂單詳情頁裡面,大部分都是訂單的快照資訊,可能有個別資訊是需要呼叫其他的介面進行展示的,但這個資訊不是必要的,此時就可以在呼叫這個介面的地方加開關,平時關閉,大促之前開啟,不進行呼叫,這樣就保證了詳情頁的穩定性。

虛擬碼如下:

boolean switch = false;
XxxInfo xxxInfo = null;
if (!switch) {
  // 呼叫外部介面獲取資訊
  xxxInfo = xxxRpc.getxxx();
}

開關注意點

開關雖然很有用,但是凡事有利也有弊。當專案中出現了很多的開關之後,對於程式碼的可讀性比較差,特別是對於新同學來說,這麼多開關,可能也不知道幹嘛的,所以第一點就是註釋一定要寫清楚。

然後對於那些保證上線穩定性的開關,在上線後過一點時間,功能穩定了,就應該及時刪除開關的邏輯,提高程式碼可讀性。對於降級的開關,還是要保留的。

開關總結

我相信大家在工作中也會用開關去做一些事情,特別是在上線新功能,或者改老功能,或者重構的時候,真的很有用。

有了開關,上線不慌,沒有開關,聽天由命。想不想保住工作,就看你開關用的溜不溜啦!