灰度發(fā)布(又名金絲雀發(fā)布)是指在黑與白之間订雾,能夠平滑過渡的一種發(fā)布方式肢预。在其上可以進行A/B testing,即讓一部分用戶繼續(xù)用產(chǎn)品特性A洼哎,一部分用戶開始用產(chǎn)品特性B烫映,如果用戶對B沒有什么反對意見,那么逐步擴大范圍噩峦,把所有用戶都遷移到B 上面來锭沟。灰度發(fā)布可以保證整體系統(tǒng)的穩(wěn)定识补,在初始灰度的時候就可以發(fā)現(xiàn)族淮、調(diào)整問題,以保證其影響度凭涂。
1、在代碼中做切油。
一套線上環(huán)境蝙斜,代碼中做開關,對于不同的用戶走不同的邏輯
2澎胡、在接入層做孕荠。
多套(隔離的)線上環(huán)境,接入層針對不同用戶轉發(fā)到不同的環(huán)境中
兩種方案的優(yōu)缺點:
方案優(yōu)點缺點
在代碼中做靈活攻谁,粒度細稚伍;一套代碼(環(huán)境)運維成本低灰度邏輯侵入代碼
在接入層做無需(少)侵入代碼;風險小多套線上環(huán)境巢株,運維成本高
靈活的灰度方案一般需要在接入層實現(xiàn)槐瑞,具體就是自定義負載均衡策略實現(xiàn)熙涤。
下面介紹在接入層使用的方式阁苞,第一是在nginx層實現(xiàn)(使用ngx+lua)困檩,第二是在網(wǎng)關層實現(xiàn)(spring-cloud-zuul)。
第三是dubbo的灰度那槽,項目中如果使用dubbo悼沿,有可能會需要dubbo服務的灰度實現(xiàn)。
負載均衡又可分為服務端負載均衡和客戶端負載均衡
服務器端負載均衡:例如Nginx骚灸,通過Nginx進行負載均衡糟趾,先發(fā)送請求,然后通過負載均衡算法甚牲,在多個服務器之間選擇一個進行訪問义郑;即在服務器端再進行負載均衡算法分配。
客戶端負載均衡:例如ribbon或者dubbo丈钙,客戶端會有一個服務器地址列表非驮,在發(fā)送請求前通過負載均衡算法選擇一個服務器,然后進行訪問雏赦,這是客戶端負載均衡劫笙;即在客戶端就進行負載均衡算法分配。
Nginx是一款輕量級的Web服務器/反向代理服務器以及電子郵件代理服務器填大。
nginx.cof
負載均衡策略:輪詢(默認)、weight俏橘、ip_hash允华、fair(響應時間)、url_hash
簡單的根據(jù)cookie進行灰度
Openresty
Nginx有很多的特性和好處寥掐,但是在Nginx上開發(fā)成了一個難題例获,Nginx模塊需要用C開發(fā),而且必須符合一系列復雜的規(guī)則曹仗,最重要的用C開發(fā)模塊 必須要熟悉Nginx的源代碼榨汤,使得開發(fā)者對其望而生畏。為了開發(fā)人員方便怎茫,所以接下來我們要介紹一種整合了Nginx和lua的框架收壕,那就是OpenResty。
OpenResty??是一個基于?Nginx?與 Lua 的高性能 Web 平臺轨蛤,其內(nèi)部集成了大量精良的 Lua 庫蜜宪、第三方模塊以及大多數(shù)的依賴項。用于方便地搭建能夠處理超高并發(fā)祥山、擴展性極高的動態(tài) Web 應用圃验、Web 服務和動態(tài)網(wǎng)關。
?Openresty學習地址:https://moonbingbing.gitbooks.io/openresty-best-practices/content/base/intro.html
新浪微博開源項目
git地址:https://github.com/CNSRE/ABTestingGateway
ABTestingGateway是一個可以動態(tài)設置分流策略的灰度發(fā)布系統(tǒng)缝呕,工作在7層澳窑,基于nginx和ngx-lua開發(fā)斧散,使用 redis 作為分流策略數(shù)據(jù)庫,可以實現(xiàn)動態(tài)調(diào)度功能摊聋。
ABTestingGateway是在 nginx 轉發(fā)的框架內(nèi)鸡捐,在轉向 upstream 前,根據(jù) 用戶請求特征 和 系統(tǒng)的分流策略 麻裁,查找出目標upstream箍镜,進而實現(xiàn)分流。
nginx實現(xiàn)的灰度系統(tǒng)中煎源,分流邏輯往往通過 rewrite 階段的 if 和rewrite 指令等實現(xiàn)色迂,優(yōu)點是性能較高,缺點是功能受限手销、容易出錯脚草,以及轉發(fā)規(guī)則固定,只能靜態(tài)分流原献。針對這些缺點馏慨, ABTestingGateway,采用ngx-lua 實現(xiàn)系統(tǒng)功能姑隅,通過啟用lua-shared-dict和lua-resty-lock作為系統(tǒng)緩存和緩存鎖写隶,系統(tǒng)獲得了較為接近原生nginx轉發(fā)的性能竿奏。
架構圖:
特性:
實現(xiàn)原理:在代理轉發(fā)前荆几,使用rewrite_by_lua_file模塊重寫到目標upstream
diversion.lua邏輯:
例:略
Dubbo架構
?? Dubbo服務調(diào)用過程
Loadbalance(負載均衡)說明
在集群負載均衡時荆忍,Dubbo 提供了多種均衡策略,缺省為?random?隨機調(diào)用
負載均衡策略Random(隨機)沮协、RoundRobin(輪詢)住册、LeastActive(最小活躍調(diào)用數(shù))牢屋、ConsistentHash(一致性Hash)
負載均衡配置:
自定義負載均衡實現(xiàn):
例:
實現(xiàn)LoadBalance接口趁矾,或者繼承AbstractLoadBalance?重寫策略耙册;
根據(jù)dubbo SPI發(fā)現(xiàn)機制,還需要在resources下添加META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance
demo邏輯:目標服務的端口和灰度服務端口的一致毫捣,并且請求方法的第一個參數(shù)類型是Long(userId)并且是灰度用戶详拙,則判斷為灰度服務,否則按照默認隨機調(diào)用其余非灰度服務
?? Ribbon 提供了幾個負載均衡的組件饶辙,其目的就是讓請求轉給合適的服務器處理
默認輪詢
自定義策略需要繼承AbstractLoadBalancerRule
開源方案:
自定義DiscoveryEnabledRule繼承PredicateBaseRule
首先在請求開始處,實現(xiàn)自己的灰度邏輯斑粱,比如下面的demo根據(jù)請求url如果包含‘version’向holder中添加route為A的標識弃揽,否則添加route為B的標識。 ?(Holder本質是一個localThread)
在目標服務添加matadateMap
PredicateBaseRule中使用google提供的pridicate,MetadataAwarePredicate中實現(xiàn)apply方法判斷發(fā)現(xiàn)的服務是否是目標服務