微服務(wù)版本分支管理與特性開關(guān)

在微服務(wù)的開發(fā)中, 我們會開發(fā)很多功能, 并在最短時間內(nèi)上線, 也就是說經(jīng)過了單元測試, API 測試, 自動化的集成測試, 以及少量的手動端到端的測試, 新增的改動就會在幾天內(nèi)部署到產(chǎn)品線上.

這樣做符合"唯快不破"的理念, 而且很多開發(fā)人員也充滿自信, 不過畢竟風(fēng)險太大, 產(chǎn)線出問題, 影響了客戶使用可不是鬧著玩的. 為穩(wěn)妥起見, 最好還是做灰度發(fā)布, 并且加一個開關(guān), 一旦出問題, 馬上對部分或全體用戶關(guān)閉最新改動. 這個開關(guān), 我們就叫做 Feature Toggle 特性開關(guān).

我所在的開發(fā)團隊以前采用過一種叫 Train Release 方式來發(fā)布產(chǎn)品, 一個大的 Train Release 包含多個組件, 既有PC客戶端 (windows/macos/linux), 移動客戶端 (ios/android), Web 站點和服務(wù), 后臺多種專用服務(wù)器.

我們一般分為三個大類

  • Web: 各種 Web 站點以及管理工具
  • Client: PC/Mobile 客戶端
  • Server: 各種后臺服務(wù)

每個大類又分為多個子類, 一個 train release 通常要做大半年, 有專門的 release manager 負責(zé)協(xié)調(diào), 開發(fā)工程師發(fā)布新版本后, 還要經(jīng)歷 ATS/BTS/Production 的升級, 部署, 測試, 試用, 最終新版本交付到用戶手中經(jīng)常歷時一年, 這就算比較順利的了, 如果中間出現(xiàn)了什么周折風(fēng)波, 一年多新版本才能上線.

這個玩法顯然沒辦法滿足用戶的急迫的需求, 于是新的版本管理方法應(yīng)運而生. 對于單個微服務(wù)來說, 我們希望能隨時發(fā)布和上線,只要它通過了構(gòu)建流水線的層層檢查和測試, 可是對于整個系統(tǒng)來說, 成千上百個微服務(wù)每天不停地升級部署, 難免會在彼此集成的接口和流程方面有所疏漏, 所有我們對主要的幾個產(chǎn)品線實施了 monthly release, 即每月發(fā)布一個版本. 當(dāng)然, 重大問題的緊急修復(fù)是可以隨時發(fā)布上線的.

  1. 月初: 主要需要和設(shè)計基本就緒
  2. 月中: 主要功能完成, 集成測試開始
  3. 月底: 經(jīng)項目負責(zé)人及主要干系人驗收通過, 發(fā)布新版本

現(xiàn)代的微服務(wù)提倡小迭代, 快修改, 快上線, 每月只能上一個版本, 這顯然不能滿足快速持續(xù)交付的需求, 但是產(chǎn)品的穩(wěn)定性是必需保證的, 既不能由于頻繁部署而導(dǎo)致系統(tǒng)出現(xiàn)問題, 也不能因噎廢食限制新版本上線的頻率.

如果我們想每天上線新的版本, 我們就必須要做好分支管理, 版本管理和特性開關(guān)的控制

分支管理

分支類型 Branch Types:

  • master branch 主分支
  • feature branch 功能分支
  • dev branch 開發(fā)分支
  • hot-fix branch 緊急修復(fù)分支

分支策略 Branch Strategy :

  • 小步快走, 多個開發(fā)分支, 一人一個, 未完成單元測試不準合并到其他分支
  • 采用少量或很短生命周期的 feature branch, 未完成集成測試不準合并到主分支
  • 產(chǎn)品分布只能在主分支上
  • 月度新功能在測試驗收之前放在 feature branch 上
    每日從主分支更新改動,并在月底測試驗收通過后合并到主分支, 并打上標簽 tag
  • 緊急修復(fù)放在 hotfix 分支上
    代碼審查和測試過后, 立即合并到主分支

版本管理

軟件應(yīng)用都有一個版本, 微服務(wù)也是如此, 版本可以用如下形式

mainVersion.minorVersion.microVersion.patchVersion

比如 2.2.0.147, 2.2.1.12, 四個小節(jié)夠了, 不宜過多

在產(chǎn)品的 API 中, 我們通常還會加上 git commit 信息
比如

GET https://mdd.example.com/mdd/api/v1/build_info

{
    "version": "2.2.1",
    "buildNumber": "247",
    "gitTag": "2.2.1.247",
    "gitCommit": "c8c30d043982c902202d436564b2fd726e61de32",
    "gitBranch": "master"
}

新版本替換舊版本總有一個過程, 如果服務(wù)器比較少, 可以快速一次級升級, 但是對于大型 SaaS 服務(wù)提供商, 服務(wù)器數(shù)量至少上千臺, 集群上百個, 數(shù)據(jù)中心遍布全球, 時區(qū)都不相同, 不可能一步到位. 同時, 由于對新版本新功能的穩(wěn)定性,性能和運行效果并非十分有底, 也會采用灰度發(fā)布的策略, 逐個集群升級,

  1. 先升級副集群, 再升級主集群
  2. 先升級小客戶, 再升級大客戶
  3. 先升級亞太區(qū), 再升級歐洲區(qū), 最后升級北美區(qū)
    為避免對客戶造成影響, 時間一般都在當(dāng)?shù)貢r間的凌晨

升級的時候應(yīng)按以下步驟進行

  1. 先檢查度量數(shù)據(jù), 確認流量在主集群上運行正常,
  2. 把備份集群設(shè)置為 suspend 狀態(tài), 也就是在共享的數(shù)據(jù)存儲表中改一下狀態(tài), 確保流量不會跑到備份集群上.
  3. 把備份集群中服務(wù)器逐個升級到最新版本
  4. 在備份集群上作一些簡單的驗證測試, 運行若干主要的 TaP 測試用例, 看測試結(jié)果是否有問題, 如果有問題, 且不是環(huán)境問題, 嚴重性不容輕視, 則立即回滾, 此次升級取消
  5. 觀察度量數(shù)據(jù), 確認已經(jīng)沒有活躍的用戶在主集群上
  6. 將主集群設(shè)為 suspend 狀態(tài), GSLB 會根據(jù) Health Check 的響應(yīng)把流量分派到備份集群, 再重復(fù)上述 3, 4步, 升級主集群

由于升級需要一個過程, 產(chǎn)線上總有一段時間存在兩個或兩個以上的版本, 如果不加區(qū)分, 用戶會比較困惑, 一會兒界面不一樣了, 一會兒功能又變了, 過了一會兒, 可能又變回來了.

在 Sharding 比較嚴格的系統(tǒng), 這個問題并不突出, 不同的用戶會落在對應(yīng)的特定集群上, 不會出現(xiàn)上述變來變?nèi)サ那闆r.
我們做過的一個系統(tǒng)為了充分利用系統(tǒng)資源, 采用了在數(shù)據(jù)中心內(nèi)部根據(jù)用量分派流量的設(shè)計, 這時就必須要好好考慮這個問題.

于是, 我們就引入了特性開關(guān)這個利器

特性開關(guān) Feature Toggle

僅靠版本難以解決上面提到的用戶體驗因為版本變化造成的功能與界面來回變化的問題, 這時候, 我們應(yīng)該使用特性開關(guān) Feature Toggle

開關(guān)的類型

  1. feature/function toggle 功能開關(guān)
  2. release toggle 發(fā)布開關(guān)
  3. operation toggle 運維開關(guān)
  4. Permission toggle 授權(quán)開關(guān)
  5. Experiment toggle 體驗開關(guān)

這里, 我們主要討論功能或特性開關(guān)和發(fā)布開關(guān)

特性開關(guān)的層次

  • organization 組織
  • site 站點
  • user 用戶
  • device 設(shè)備

特性開關(guān)的使用

前面我們提到開關(guān)有五種類型, 不同類型有不同的應(yīng)用場景

A/B 測試

在一部分站點上打開開關(guān), 另一部分站點上關(guān)閉開關(guān), 互相對照測試, 收集并觀察度量數(shù)據(jù)
也可以直接把開關(guān)的設(shè)置開放給用戶, 用戶按自己的喜好選擇, 在站點改版常用這一招來看用戶是否接受和喜歡新的變化

用戶試用

針對特定的用戶群體, 打開開關(guān)供用戶試用和測試

特性發(fā)布

待所有所需最低版本都已升級部署完畢, 打開所有的相關(guān)特性開關(guān), 正式發(fā)布這一新功能

特性開關(guān)服務(wù) Feature Service

我們可以開發(fā)一個 Feature Service, 可以供開發(fā)和運維人員調(diào)用它的 API 來設(shè)置 Feature Toggle, 其他的 Service 可以調(diào)用它的 API 來讀取這些 Feature Toggle 來決定應(yīng)用不同的邏輯和行為, 而所有這些操作無需重啟服務(wù)進程和更改配置文件.

FeatureToggle 比較簡單的就定義一個布爾值 true or false , yes or no, 或者 on or off

比如

{
"enableAutoLogout": true
}

稍微復(fù)雜的可以有枚舉值: off, test, on, 并且加上失效時間

{
"enableAutoLogout": "test",
"expireTime": "2018-12-31T23:59:59Z"
}

以 user level 的 feature toggle 舉例如下

  • 設(shè)置 Feature Toggle
POST /featuretoggles/users

{
    "userIds": ["123", "456", "789"],
    "featureToggles":
    [
        {
            "key": "enableAutoLock",
            "value" "true"
        },
        {
            "key": "enableAutoLogin",
            "value" "true"
        }
    ]
}
  • 讀取 Feature Toggle
GET /featuretoggles/users/:userId

{
    "featureToggles":
    [
        {
            "key": "enableAutoLock",
            "value" "true"
        },
        {
            "key": "enableAutoLogin",
            "value" "true"
        }
    ]
}

具體的實現(xiàn)很簡單, 利用傳統(tǒng)DB 或者 Redis, Cassandra 這樣的 NOSQL 存儲讀寫就可以了, 存儲結(jié)構(gòu)示例如下

Table FeatureToggle:

level Id toggleName toggleValue
org 123 enableRateLimit true
site 456 enableCircuitBreaker true
user 789 enableAutoLock true

相關(guān)類庫

Java 工具庫

  • Togglz
  • FF4J
  • Fitchy
  • Flip

Python 工具庫

  • Gargoyle
  • Gutter

.NET, C# 工具庫

  • FeatureSwitcher
  • NFeature
  • FlipIt
  • FeatureToggleNET
  • List on NUget
  • FeatureBee

Ruby and Ruby on Rails 工具庫

  • rollout
  • feature_flipper
  • flip
  • setler
  • switches
  • FluidFeatures

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Git 倉庫申請流程 1. 開發(fā)主管向Git 管理員提交Git 倉庫申請【郵件:發(fā)送給Git 管理員,抄送給項目經(jīng)...
    騷包霸天虎閱讀 2,228評論 0 0
  • 寫作于:2016-09 修改于:2017-12 引言 微服務(wù)體系的發(fā)展并不是一蹴而就的,經(jīng)過了2014年前后的低潮...
    巾梵閱讀 1,868評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 1 Git Flow介紹 我們都知道, 在 git 的分支功能相對 svn 確實方便許多,而且也非常推薦使用分支來...
    七寸知架構(gòu)閱讀 8,054評論 20 68
  • 1點多入睡,5點多醒來,腦海中全是【余歌演說】老師說的課程,感覺自己還在廈門聽課沒回來。 七月中又要帶《晉組團》了...
    藍天虹閱讀 249評論 0 0

友情鏈接更多精彩內(nèi)容