https://blog.csdn.net/hueason/article/details/81054093
一、灰度發布定義
灰度發布(又名金絲雀發布)是指在黑與白之間,能夠平滑過渡的一種發布方式。在其上可以進行A/B testing,即讓一部分用戶繼續用產品特性A,一部分用戶開始用產品特性B,如果用戶對B沒有什么反對意見,那么逐步擴大范圍,把所有用戶都遷移到B 上面來。灰度發布可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。
二、實現思路方向
1、在代碼中做。
一套線上環境,代碼中做開關,對於不同的用戶走不同的邏輯
2、在接入層做。
多套(隔離的)線上環境,接入層針對不同用戶轉發到不同的環境中
兩種方案的優缺點:
方案 |
優點 |
缺點 |
在代碼中做 |
靈活,粒度細;一套代碼(環境)運維成本低 |
灰度邏輯侵入代碼 |
在接入層做 |
無需(少)侵入代碼;風險小 |
多套線上環境,運維成本高 |
靈活的灰度方案一般需要在接入層實現,具體就是自定義負載均衡策略實現。
下面介紹在接入層使用的方式,第一是在nginx層實現(使用ngx+lua),第二是在網關層實現(spring-cloud-zuul)。
第三是dubbo的灰度,項目中如果使用dubbo,有可能會需要dubbo服務的灰度實現。
負載均衡又可分為服務端負載均衡和客戶端負載均衡
服務器端負載均衡:例如Nginx,通過Nginx進行負載均衡,先發送請求,然后通過負載均衡算法,在多個服務器之間選擇一個進行訪問;即在服務器端再進行負載均衡算法分配。
客戶端負載均衡:例如ribbon或者dubbo,客戶端會有一個服務器地址列表,在發送請求前通過負載均衡算法選擇一個服務器,然后進行訪問,這是客戶端負載均衡;即在客戶端就進行負載均衡算法分配。
三、nginx灰度方案說明
Nginx是一款輕量級的Web服務器/反向代理服務器以及電子郵件代理服務器。
nginx.cof
負載均衡策略:輪詢(默認)、weight、ip_hash、fair(響應時間)、url_hash
簡單的根據cookie進行灰度
Openresty
Nginx有很多的特性和好處,但是在Nginx上開發成了一個難題,Nginx模塊需要用C開發,而且必須符合一系列復雜的規則,最重要的用C開發模塊 必須要熟悉Nginx的源代碼,使得開發者對其望而生畏。為了開發人員方便,所以接下來我們要介紹一種整合了Nginx和lua的框架,那就是OpenResty。
OpenResty® 是一個基於 Nginx 與 Lua 的高性能 Web 平台,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。用於方便地搭建能夠處理超高並發、擴展性極高的動態 Web 應用、Web 服務和動態網關。
Openresty學習地址:https://moonbingbing.gitbooks.io/openresty-best-practices/content/base/intro.html
新浪微博開源項目
git地址:https://github.com/CNSRE/ABTestingGateway
ABTestingGateway是一個可以動態設置分流策略的灰度發布系統,工作在7層,基於nginx和ngx-lua開發,使用 redis 作為分流策略數據庫,可以實現動態調度功能。
ABTestingGateway是在 nginx 轉發的框架內,在轉向 upstream 前,根據 用戶請求特征 和 系統的分流策略 ,查找出目標upstream,進而實現分流。
nginx實現的灰度系統中,分流邏輯往往通過 rewrite 階段的 if 和rewrite 指令等實現,優點是性能較高
,缺點是功能受限
、容易出錯
,以及轉發規則固定,只能靜態分流
。針對這些缺點, ABTestingGateway,采用ngx-lua 實現系統功能,通過啟用lua-shared-dict和lua-resty-lock作為系統緩存和緩存鎖,系統獲得了較為接近原生nginx轉發的性能。
架構圖:
特性:
實現原理:在代理轉發前,使用rewrite_by_lua_file模塊重寫到目標upstream
diversion.lua邏輯:
例:略
四、dubbo灰度方案說明
Dubbo架構
Dubbo服務調用過程
Loadbalance(負載均衡)說明
在集群負載均衡時,Dubbo 提供了多種均衡策略,缺省為 random
隨機調用
負載均衡策略Random(隨機)、RoundRobin(輪詢)、LeastActive(最小活躍調用數)、ConsistentHash(一致性Hash)
負載均衡配置:
自定義負載均衡實現:
例:
實現LoadBalance接口,或者繼承AbstractLoadBalance 重寫策略;
根據dubbo SPI發現機制,還需要在resources下添加META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance
demo邏輯:目標服務的端口和灰度服務端口的一致,並且請求方法的第一個參數類型是Long(userId)並且是灰度用戶,則判斷為灰度服務,否則按照默認隨機調用其余非灰度服務
四、springCloud灰度方案說明
Ribbon 提供了幾個負載均衡的組件,其目的就是讓請求轉給合適的服務器處理
默認輪詢
自定義策略需要繼承AbstractLoadBalancerRule
開源方案:
自定義DiscoveryEnabledRule繼承PredicateBaseRule
首先在請求開始處,實現自己的灰度邏輯,比如下面的demo根據請求url如果包含‘version’向holder中添加route為A的標識,否則添加route為B的標識。 (Holder本質是一個localThread)
在目標服務添加matadateMap
PredicateBaseRule中使用google提供的pridicate,MetadataAwarePredicate中實現apply方法判斷發現的服務是否是目標服務