灰度值怎么降级_微服务生态的灰度发布如何实现?
前言
相信很多小伙伴們都聽說過灰度發(fā)布,但是不一定知道如何實(shí)現(xiàn)?今天我們就介紹一下基本原理,以及提供代碼實(shí)現(xiàn)給小伙伴們。
灰度概念
即原來的生產(chǎn)環(huán)境是1.0版本,那現(xiàn)在我們需要升級到2.0版本,但是我們需要驗(yàn)證2.0版本,在生產(chǎn)環(huán)境不會(huì)出問題,而且要穩(wěn)定后,才能夠完全切換為2.0。
小伙伴們就會(huì)問,2.0版本應(yīng)該我們測試人員 測試了啊,肯定沒有問題啊。升級到2.0,直接升級就行了啊。
這個(gè)是不對的,因?yàn)?strong>生產(chǎn)環(huán)境有很多場景是獨(dú)有的,如用戶流量,數(shù)據(jù)量等。所以必須要驗(yàn)證2.0的穩(wěn)定性;升級步驟如下:
1)100%的用戶流量打到1.0版本上面;但測試人員可以通過測試工具指定線上2.0版本,即測試人員請求的是2.0版本。2)測試初步驗(yàn)證后,可以先分5%的用戶流量到2.0版本,95%的用戶流量還是在1.0版本3)查看2.0的穩(wěn)定情況,分階段的分配用戶流量4)完成切換到2.0版本,下線1.0版本;在下線1.0版本的時(shí)候不同的方案 會(huì)遇到不同的坑實(shí)現(xiàn)原理一
老顧這個(gè)灰度的框架是建立在springcloud alibaba生態(tài)的,注冊中心和配置中心都是使用的是nacos;我們先來看看整個(gè)系統(tǒng)架構(gòu),在升級狀態(tài)是什么情況:
在spring cloud中,不管是網(wǎng)關(guān) -> 服務(wù)A -> 服務(wù)B -> 服務(wù)C整個(gè)請求,網(wǎng)關(guān)是怎么知道有哪些服務(wù)A的?服務(wù)A是怎么知道有哪些服務(wù)B?服務(wù)B有哪些服務(wù)C?
這個(gè)是因?yàn)槲覀兊乃蟹?wù)都注冊到了nacos注冊中心里面,然后每個(gè)服務(wù)實(shí)例會(huì)通過5秒的心跳去請求nacos,獲取到nacos里面的注冊信息。
這個(gè)就是很重要的一個(gè)點(diǎn),服務(wù)信息的同步;我們可以重寫每個(gè)服務(wù)實(shí)例去拉取服務(wù)信息的時(shí)候,做一些過濾處理。舉個(gè)例子,我們怎么保證服務(wù)A(1.0)只訪問服務(wù)B(1.0)。
服務(wù)A(1.0)在調(diào)用服務(wù)B時(shí),需要去拉取服務(wù)B的服務(wù)實(shí)例信息,當(dāng)我們發(fā)現(xiàn)服務(wù)B中有2.0版本時(shí),就直接過濾掉;1.0才同步到本地緩存;通過這原理,就是保證了服務(wù)A(1.0)實(shí)例,只能訪問服務(wù)B(1.0)
那怎么重寫拉取服務(wù)呢?就是繼承NacosServerList重寫getInitialListOfServers、getUpdatedListOfServers方法,直接上源代碼。
實(shí)現(xiàn)原理二
只實(shí)現(xiàn)過濾掉不需要的版本,是不夠的;因?yàn)槲覀冇辛硪粋€(gè)需求,就是流量權(quán)重;即服務(wù)A可以訪問服務(wù)B(1.0),也就是訪問服務(wù)B(2.0);只是流量權(quán)重占比不一樣而已;那怎么實(shí)現(xiàn)呢?
那就要用到我們客戶端client的rabbion組件了,這個(gè)組件主要用來調(diào)用服務(wù)實(shí)例的,而是可以實(shí)現(xiàn)負(fù)載均衡;那我們就可以重寫負(fù)載均衡算法,實(shí)現(xiàn)自定義的流量權(quán)重這個(gè)需求。
具體實(shí)現(xiàn)就是繼承ZoneAvoidanceRule
重寫Server choose(Object key),直接上代碼
public class ZoneAvoidanceRuleDecorator extends ZoneAvoidanceRule { 。。。。。。 @Override? ? public Server choose(Object key) { //todo 選擇的邏輯 }}知道了基本的原理后,就可以直接去寫了。
實(shí)現(xiàn)原理三
另一個(gè)需求,就是我們需要考慮到在線動(dòng)態(tài)的改變灰度路由的規(guī)則,而不是每次改變了規(guī)則,需要重新啟動(dòng)服務(wù),這個(gè)就不對了。
這個(gè)的實(shí)現(xiàn)可以考慮利用nacos自身的功能。去訂閱nacos的配置中心的變化,從而達(dá)到動(dòng)態(tài)更新。
案例
因?yàn)槠?#xff0c;老顧這里只介紹一些原理,具體源代碼,可以到git上面去獲取,要給個(gè)star哦。
https://gitee.com/gujiachun/gray引入依賴
1、微服務(wù)項(xiàng)目需引入gray-plugin-framework-starter-service項(xiàng)目。
<dependency>? ?<groupId>com.rainbow.graygroupId>? ?<artifactId>gray-plugin-framework-starter-serviceartifactId>? ?<version>1.0.0-SNAPSHOTversion>dependency>2、網(wǎng)關(guān)項(xiàng)目需引入gray-plugin-framework-starter-gateway項(xiàng)目。
<dependency>? ?<groupId>com.rainbow.graygroupId>? ?<artifactId>gray-plugin-framework-starter-gatewayartifactId>? ?<version>1.0.0-SNAPSHOTversion>dependency>3、本組件推薦使用遠(yuǎn)程配置的方法,配置rule規(guī)則,現(xiàn)在只支持nacos配置中心。
4、組件支持全局訂閱,或局部訂閱。
全局訂閱即:DataId = group1,Group=group1;即DataId也為group名稱,這樣每個(gè)微服務(wù)以及網(wǎng)關(guān)都只訂閱的是同一個(gè)rule規(guī)則。
局部訂閱即:DataId = 服務(wù)名稱,Group=group1;即DataID是服務(wù)名稱,即只有這個(gè)服務(wù)訂閱了rule規(guī)則;其他服務(wù)不適用。
(推薦全局訂閱,因?yàn)榛叶劝l(fā)布一般針對所有的服務(wù)生效;而且規(guī)則里面可以細(xì)化到每個(gè)服務(wù)的規(guī)則)
規(guī)則說明
使用說明
1、配置nacos,在bootstrap.properties中配置nacos注冊中心。
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848spring.cloud.nacos.discovery.username=nacosspring.cloud.nacos.discovery.password=nacosspring.cloud.nacos.discovery.namespace=sit2、在bootstrap.properties中組件需要的配置。
nacos.server-addr=${spring.cloud.nacos.discovery.server-addr}nacos.username=${spring.cloud.nacos.discovery.username}nacos.password=${spring.cloud.nacos.discovery.password}nacos.plugin.namespace=${spring.cloud.nacos.discovery.namespace}3、在application.properties 配置元數(shù)據(jù),非常重要,這個(gè)就是每個(gè)服務(wù)不同的版本version,地域region,環(huán)境env,區(qū)zone相關(guān)的配置。
spring.cloud.nacos.discovery.metadata.group=example-service-groupspring.cloud.nacos.discovery.metadata.version=1.0spring.cloud.nacos.discovery.metadata.region=devspring.cloud.nacos.discovery.metadata.env=env1spring.cloud.nacos.discovery.metadata.zone=zone14、親和性
啟動(dòng)和關(guān)閉可用區(qū)親和性,即同一個(gè)可用區(qū)的服務(wù)才能調(diào)用,同一個(gè)可用區(qū)的條件是調(diào)用端實(shí)例和提供端實(shí)例的元數(shù)據(jù)Metadata的zone配置值必須相等。缺失則默認(rèn)為false
spring.application.zone.affinity.enabled=true啟動(dòng)和關(guān)閉可用區(qū)親和性失敗后的路由,即調(diào)用端實(shí)例沒有找到同一個(gè)可用區(qū)的提供端實(shí)例的時(shí)候,當(dāng)開關(guān)打開,可路由到其它可用區(qū)或者不歸屬任何可用區(qū),當(dāng)開關(guān)關(guān)閉,則直接調(diào)用失敗。缺失則默認(rèn)為true
spring.application.zone.route.enabled=true外部參數(shù)Header
通過前端(Postman)方式傳入灰度路由策略,來代替配置中心方式,傳遞全鏈路路由策略。這樣就可以實(shí)現(xiàn)由測試人員自行選擇走哪些路徑。
注意:當(dāng)配置中心和外部參數(shù)都配置后,會(huì)先從配置中心的規(guī)則會(huì)先過濾執(zhí)行,然后外部參數(shù)再過濾的原則
-版本匹配策略,Header格式如下任選一個(gè)
n-d-version=1.0n-d-version={"discovery-guide-service-a":"2.0", "discovery-guide-service-b":"2.0"}-版本權(quán)重策略,Header格式如下任選一個(gè)
n-d-version-weight=1.0=90;1.1=10n-d-version-weight={"discovery-guide-service-a":"1.0=90;1.1=10", "discovery-guide-service-b":"1.0=90;1.1=10"}-區(qū)域匹配策略,Header格式如下任選一個(gè)
n-d-region=qan-d-region={"discovery-guide-service-a":"qa", "discovery-guide-service-b":"qa"}-區(qū)域權(quán)重策略,Header格式如下任選一個(gè)
n-d-region-weight=dev=99;qa=1n-d-region-weight={"discovery-guide-service-a":"dev=99;qa=1", "discovery-guide-service-b":"dev=99;qa=1"}-IP地址和端口匹配策略,Header格式如下任選一個(gè)
n-d-address={"discovery-guide-service-a":"127.0.0.1:3001", "discovery-guide-service-b":"127.0.0.1:4002"}n-d-address={"discovery-guide-service-a":"127.0.0.1", "discovery-guide-service-b":"127.0.0.1"}n-d-address={"discovery-guide-service-a":"3001", "discovery-guide-service-b":"4002"}-環(huán)境隔離下動(dòng)態(tài)環(huán)境匹配策略
n-d-env=env1-服務(wù)下線實(shí)時(shí)性的流量絕對無損,全局唯一ID屏蔽策略
n-d-id-blacklist=e92edde5-0153-4ec8-9cbb-b4d3f415aa33;af043384-c8a5-451e-88f4-457914e8e3bc-服務(wù)下線實(shí)時(shí)性的流量絕對無損,IP地址和端口屏蔽策略
n-d-address-blacklist=192.168.43.101:1201;192.168.*.102;1301當(dāng)外界傳值Header的時(shí)候,網(wǎng)關(guān)也設(shè)置并傳遞同名的Header,需要決定哪個(gè)Header傳遞到后邊的服務(wù)去。需要通過如下開關(guān)做控制:
# 當(dāng)外界傳值Header的時(shí)候,網(wǎng)關(guān)也設(shè)置并傳遞同名的Header,需要決定哪個(gè)Header傳遞到后邊的服務(wù)去。如果下面開關(guān)為true,以網(wǎng)關(guān)設(shè)置為優(yōu)先,否則以外界傳值為優(yōu)先。缺失則默認(rèn)為truespring.application.strategy.gateway.header.priority=false# 當(dāng)以網(wǎng)關(guān)設(shè)置為優(yōu)先的時(shí)候,網(wǎng)關(guān)未配置Header,而外界配置了Header,仍舊忽略外界的Header。缺失則默認(rèn)為truespring.application.strategy.gateway.original.header.ignored=true# 當(dāng)外界傳值Header的時(shí)候,網(wǎng)關(guān)也設(shè)置并傳遞同名的Header,需要決定哪個(gè)Header傳遞到后邊的服務(wù)去。如果下面開關(guān)為true,以網(wǎng)關(guān)設(shè)置為優(yōu)先,否則以外界傳值為優(yōu)先。缺失則默認(rèn)為truespring.application.strategy.zuul.header.priority=false# 當(dāng)以網(wǎng)關(guān)設(shè)置為優(yōu)先的時(shí)候,網(wǎng)關(guān)未配置Header,而外界配置了Header,仍舊忽略外界的Header。缺失則默認(rèn)為truespring.application.strategy.zuul.original.header.ignored=true總結(jié)
整體灰度的功能還是挺多,不過實(shí)現(xiàn)的原理就是上面介紹的原理;這里也要感謝開源社區(qū)的nepxion discovery開源項(xiàng)目,借鑒了設(shè)計(jì)思路,以及一些代碼設(shè)計(jì),簡化了實(shí)現(xiàn)。
分享、在看與點(diǎn)贊都在這兒點(diǎn)下給小編加點(diǎn)料總結(jié)
以上是生活随笔為你收集整理的灰度值怎么降级_微服务生态的灰度发布如何实现?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tf.contrib在tf2中无法使用
- 下一篇: 本特利3500_本特利技术控的自我修养之