全鏈路灰度在數據庫上我們是怎么做的?
什么是全鏈路灰度?
微服務體系架構中,服務之間的依賴關系錯綜復雜,有時某個功能發版依賴多個服務同時升級上線。我們希望可以對這些服務的新版本同時進行小流量灰度驗證,這就是微服務架構中特有的全鏈路灰度場景,通過構建從網關到整個后端服務的環境隔離來對多個不同版本的服務進行灰度驗證。
查看直播教程:?https://yqh.aliyun.com/live/detail/29004?
在發布過程中,我們只需部署服務的灰度版本,流量在調用鏈路上流轉時,由流經的網關、各個中間件以及各個微服務來識別灰度流量,并動態轉發至對應服務的灰度版本。如下圖:
上圖可以很好展示這種方案的效果,我們用不同的顏色來表示不同版本的灰度流量,可以看出無論是微服務網關還是微服務本身都需要識別流量,根據治理規則做出動態決策。當服務版本發生變化時,這個調用鏈路的轉發也會實時改變。相比于利用機器搭建的灰度環境,這種方案不僅可以節省大量的機器成本和運維人力,而且可以幫助開發者實時快速的對線上流量進行精細化的全鏈路控制。
OpenSergo[1] 流量路由標準
Q:OpenSergo是什么?
A:OpenSergo 是一套開放、通用的、面向分布式服務架構、覆蓋全鏈路異構化生態的服務治理標準,基于業界服務治理場景與實踐形成服務治理通用標準。OpenSergo 的最大特點是以統一的一套配置/DSL/協議定義服務治理規則,面向多語言異構化架構,做到全鏈路生態覆蓋。無論微服務的語言是Java, Go, Node.js還是其它語言,無論是標準微服務還是 Mesh 接入,從網關到微服務,從數據庫到緩存,從服務注冊發現到配置,開發者都可以通過同一套OpenSergo CRD標準配置針對每一層進行統一的治理管控,而無需關注各框架、語言的差異點,降低異構化、全鏈路服務治理管控的復雜度
Q:為什么了解全鏈路灰度之前先給我介紹 OpenSergo?
A:OpenSergo 定義了一套統一的 YAML 配置方式來針對分布式架構進行全鏈路的服務治理的規范,介紹規范與標準的同時,我們可以了解其中的技術細節的實現,同時我們還可以將新的組件與 OpenSergo 的標準進行實現。
流量路由,顧名思義就是將具有某些屬性特征的流量,路由到指定的目標。流量路由是流量治理中重要的一環,開發者可以基于流量路由標準來實現各種場景,如灰度發布、金絲雀發布、容災路由、標簽路由等。
全鏈路灰度示例:
流量路由規則(v1alpha1) 主要分為三部分:
- Workload 標簽規則 (WorkloadLabelRule):將某一組 workload 打上對應的標簽,這一塊可以理解為是為應用或者對應存儲層的話就是數據庫負載(數據庫、表)打上對應的標簽
- 流量標簽規則 (TrafficLabelRule):將具有某些屬性特征的流量,打上對應的標簽
- 按照 Workload 標簽和流量標簽來做匹配路由,將帶有指定標簽的流量路由到匹配的 workload 中
給流量打標:
需要將具有某些屬性特征的流量,打上對應的標簽。
假設現在需要將深圳地域的用戶灰度到新版主頁,測試用戶 locatinotallow=cn-shenzhen,cn-shenzhen 位于 location header 中:
通過上述配置,location header 為 cn-shenzhen 的 HTTP 流量,打上 gray 標,代表這個流量為灰度流量。
給 Workload 打標簽:
在使用 Nacos 作為服務發現的業務系統中,一般是需要業務根據其使用的微服務框架來決定打標方式。如果 Java 應用使用的 Spring Cloud 微服務開發框架,我們可以為業務容器添加對應的環境變量來完成標簽的添加操作。比如我們希望為節點添加版本灰度標,那么為業務容器添加
http://traffic.opensergo.io/label: gray ,這樣框架向 Nacos 注冊該節點時會為其添加一個 gray 標簽。
對于一些復雜的 workload 打標場景(如數據庫實例、緩存實例標簽),我們可以利用 WorkloadLabelRule CRD 進行打標。示例:
全鏈路灰度在數據庫上的常見方案
方案一:影子庫
每個單獨維護一套獨立的庫,假設基線環境的庫的名稱為 mse-demo,那么 gray 環境的流量可以映射到 mse-demo-gray 的庫中,我們在同一個實例上建立對應環境流量的影子庫,我們在業務中維護著各個庫連接的連接池,根據不同的流量標選擇對應的影子庫的連接去訪問,以此達到數據和基線環境庫隔離的效果,從而避免了灰度環境流量產生的數據對基線環境庫造成污染。
方案二:影子表
類似影子庫方案,針對影子表方案,是在同一個實例上的同一個數據庫上建立對應的影子表。我們在執行 SQL 的過程中,對灰度流量的 SQL 進行解析與修改,實現不同環境流量的 SQL 分別訪問對應的表,假設基線環境的表的名稱為 mse_demo_table,那么 gray 環境的流量可以映射到 mse_demo_table_gray 的表中。從而實現灰度數據和基線環境數據表隔離的效果。
MSE[2] 數據庫全鏈路灰度能力
MSE 提供了一種數據隔離的方案,您可以在不需要修改任何業務代碼的情況下,實現數據庫層面全鏈路灰度。下面介紹 MSE 基于 Mysql 數據存儲通過影子表的方案實現全鏈路灰度的能力。
前提條件
- 應用接入 MSE
- 部署 Demo 應用
在阿里云容器服務中部署 A、B、C 三個應用,每個應用分別部署?個 base 版本和?個 gray 版本;并部署?個 Nacos Server 應用,用于實現服務發現。具體可參考教程完成應用部署:部署 Demo 應用程序[3]。
Demo 應用介紹,本 Demo 中的 C 應用會向數據庫執行如下語句:
其中涉及到的數據庫建表語句:
- 創建影子表,我們 Demo涉及到的數據庫表有 mse_demo_table,因為我們需要創建灰度 gray 環境,因此我們需要提前創建 mse_demo_table_gray 表。
第一步:配置全鏈路灰度規則
您需要配置完成 MSE 的全鏈路發布,具體操作細節可參考教程:配置全鏈路灰度[4]。
創建如下泳道規則:
第二步:配置數據庫全鏈路灰度
- 我們需要配置以下環境變量來額外開啟/配置數據庫的全鏈路灰度能力
第三步:結果驗證
我們發起灰度請求,發現流量請求均訪問灰度環境:
我們通過如下 SQL 查詢影子表:
發現灰度環境的數據都插入至影子表。
不僅僅是全鏈路灰度
目前為止 MSE 服務治理全鏈路灰度能力已經支持了云原生網關、ALB、APISIX、Apache Dubbo、Spring Cloud、RocketMQ 以及數據庫。在數據庫層面我們通過影子表的方式實現了數據層面的流量隔離,下一步我們會將該能力進行進一步產品化,全鏈路灰度也會支持緩存層面的能力。
服務治理是微服務改造深入到一定階段之后的必經之路,在這個過程中我們不斷有新的問題出現。
- 除了全鏈路灰度,服務治理還有沒其他能力?
- 服務治理能力有沒一個標準的定義,服務治理能力包含哪些?
- 多語言場景下,有無全鏈路的最佳實踐或者標準?
- 異構微服務如何可以統一治理?
當我們在探索服務治理的過程中,我們在對接其他微服務的時候,我們發現治理體系不同造成的困擾是巨大的,打通兩套甚者是多套治理體系的成本也是巨大的。為此我們提出了 OpenSergo 項目。OpenSergo 要解決的是不同框架、不同語言在微服務治理上的概念碎片化、無法互通的問題。