分散式中灰度方案實踐
讓請求在導航的服務節上點執行;
一、背景簡介
分散式系統中會存在這樣的開發場景,不同需求可能涉及到對同一個服務的開發,那麼該服務在研發期間就會存在多個版本並行的狀態,為了保持不同版本之間的隔離性,驗收需要將請求路由到指定版本號的服務上處理;
假設存在三個服務:A、B、C,且服務B和C都存在多個版本,那麼讓請求按照即定的路由規則執行,即可保證研發期間的驗收是版本間隔離的,並且可以實現灰度部署的策略;
二、負載策略
在微服務系統架構中,請求在服務間轉發時會執行負載的策略,尤其當服務存在多版本號的叢集模式時,很顯然常規的輪詢、權重、隨機等策略無法滿足需求;進行路由規則的自定義設計和開發是常見方式;
經典應用場景:在請求發起時,可以通過Header、Cookie、Parameter等不同的方式,攜帶路由規則的方式與引數執行匹配邏輯,從而將請求路由到指定版本的服務;
預設主分支路由
通常來說請求會在主幹分支上執行,或者其他分支路由規則不匹配,也可以通過標識配置,判斷是否由主分支兜底,甚至是存活的任意服務兜底;
存活的服務中可能存在多個版本,但是主分支Master是否存活是服務健康與否的基本標誌,常規應用中路由規則如果不匹配,會由Master服務進行兜底;
版本號統一路由
請求通過攜帶分支號進行統一版本路由是常用的輕量級方案,即如果請求攜帶的是 2.0.0
的分支,則在路由時優先匹配相關版本的服務,不匹配時由Master服務處理即可;
服務定製化路由
在請求或配置中指定各個服務的路由分支號,也是常見的匹配方案,如上圖在請求時指定服務B由 1.0.0
分支執行,服務C由 3.0.0
分支執行,其餘服務在主幹分支執行;
路由規則可以看做是對可用服務的匹配篩選,如果篩選出來的服務存在叢集部署時,還要去執行相應的負載均衡策略,例如上圖中當服務C的 3.0.0
分支是叢集時,路由匹配到該版本後,再通過負載均衡的策略選中其中一個服務處理請求;
三、灰度部署
當負載均衡的策略可以按照定製化開發的規則執行時,那服務的灰度釋出就會容易很多,在不影響現有服務的情況下發布新版本,同時將請求按照規則分流,完成對新服務的驗收後,替換掉舊版本即可;
分散式系統中子服務的拆分非常多,版本開發通常只會涉及其中部分子服務,通過灰度模式將相關服務部署到線上,並且不會影響主幹的服務,只有開啟特定的配置才會將請求分流到灰度服務;
流程細節
- 1、做好路由配置和管理,請求預設在主幹服務執行;
- 2、部署版本涉及的相關服務,灰度層面預設不會處理請求;
- 3、驗收階段基於配置,將指定規則的請求路由到灰度層;
- 4、常用規則:攜帶分支號、灰度使用者群、比例分流、IP等;
- 5、完成灰度服務驗收後,將相關服務標記為主幹服務;
- 6、將舊的主幹服務下線後,即本次上線流程完整結束;
- 7、若發現灰度服務驗收失敗,撤掉灰度層或修改都可以;
灰度釋出的模式即依賴於自定義的路由規則,以及服務在負載均衡時權重比例傾斜,這些都可以在配置中心管理,在測試時動態修改即可;
在這種模式下,灰度服務的上線或者下線幾乎是沒有明顯感知的,如果是相對簡單的流程,由測試人員驗收灰度層服務即可,如果是複雜的流程,放開一定比例的使用者流量,流程觀察沒有問題後完成升級;
四、實踐方案
1、流程設計
在灰度方案落地實踐的過程中,通常客戶端會攜帶路由規則的標識,從而將請求傳送到指定服務,在規則無法正常匹配的時候,由主幹服務處理,對於一些核心的開關標識在配置中心統一維護;
2、路由標識
標識獲取
通常情況下,路由的標識是在請求頭中攜帶的,這樣比較方便統一管理,常用的傳遞格式如下:
2.0.0 3.0.0
在微服務的元件中獲取請求頭的方式很多,比如Gateway閘道器中的路由過濾器,或者服務中的攔截器,都可以獲取請求的相關引數資訊,從而執行路由規則;
標識管理
自定義路由規則需要客戶端標識,雖然獲取請求中的標識並不複雜,但是將標識傳遞到路由規則中就涉及到上下文引數管理:
- 寫階段:在過濾或攔截中獲取路由標識,寫入上下文容器;
- 讀階段:路由時從容器中讀取標識,基於配置資訊執行規則;
請求從進入閘道器開始,在服務間通訊時會涉及負載均衡的策略,在過濾或攔截器中將標識寫到上下文容器,執行路由規則需要讀取上下文容器,如果標識不存在則預設選擇主幹服務執行請求;
3、服務選中
微服務之間通訊時,選中一個服務執行請求的邏輯比較複雜,尤其在灰度模式下涉及到對路由規則的改造,即策略指定的服務優先被選中;
- 1、從註冊中心查詢相應服務的可用列表;
- 2、基於路由規則,匹配符合請求標識的服務;
- 3、對篩選的結果列表執行負載均衡,選中服務;
在整個路由機制中,會涉及到匹配規則自定義改造,從常規的手段來看,將版本的分支號載入到服務的元資料資訊中,再結合服務名稱或者IP地址,來實現對服務列表的多維度過濾,可以支撐大部分輕量級灰度策略的實現。
五、參考原始碼
應用倉庫: http://gitee.com/cicadasmile/butte-flyer-parent 元件封裝: http://gitee.com/cicadasmile/butte-frame-parent
- 記一次批量更新整型型別的列 → 探究 UPDATE 的使用細節
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- Django 之路由層
- 【前端必會】webpack loader 到底是什麼
- day42-反射01
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 設計模式---享元模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- [ML從入門到入門] 支援向量機:從SVM的推導過程到SMO的收斂性討論
- 從應用訪問Pod元資料-DownwardApi的應用
- Springboot之 Mybatis 多資料來源實現
- Java 泛型程式設計
- CAS核心思想、底層實現