策略是通過REST或者RPC調用傳遞Header或者參數,達到用戶自定義和編程灰度路由的目的。使用者可以實現跟業務有關的路由策略,根據業務參數的不同,負載均衡到不同的服務器,其核心代碼參考discovery-plugin-strategy以及它的擴展。
可以簡單的理解,灰度策略是在程序運行期間,動態的通過改變header或者參數來實現調用鏈路的動態變更,簡單的說實現原理,就是從註冊中心獲取到的幹個版本標記的服務列表中,過濾並找到只符合配置路由策略的這條路由線路上的服務進行請求調用,不符合路由策略的服務將被避開。
除了之前講到的要引入相關的依賴包,更重要的是要是先灰度策略,配置參數的準確性非常重要
如果你的註冊中心是基於eureka
# Eureka config for discovery eureka.instance.metadataMap.group=xxx-service-group eureka.instance.metadataMap.version=1.0 eureka.instance.metadataMap.region=dev
eureka:
instance:
metadata-map:
# Eureka config for discovery
group: xxx-service-group # 服務分組
version: 1.0 # 服務版本
# region: tianjin # 區域如果沒有使用可以不填寫
如果你的註冊中心是基於nacos
# Nacos config for discovery spring.cloud.nacos.discovery.metadata.group=example-service-group spring.cloud.nacos.discovery.metadata.version=1.0 spring.cloud.nacos.discovery.metadata.region=dev
spring:
cloud:
nacos:
discovery:
metadata:
# Nacos config for discovery
group: xxx-service-group
version: 1.0
region: tianjin
作用就是首先要在metadata裏標識服務自身的版本,A服務的1實例版本1.0,如果A服務升級調整變爲版本2.0,則註冊到註冊中心的A服務實例包含2個版本 1.0和2.0
同時還有一個很重要的參數需要開啓
開啓(true)和關閉(false)用戶自定義和編程灰度路由策略的時候,對REST方式的調用攔截。缺失則默認爲false spring.application.strategy.rest.intercept.enabled=true
spring:
application:
# ----- 開啓(true)和關閉(false)用戶自定義和編程灰度路由策略的時候,對REST方式的調用攔截。缺失則默認爲false
strategy:
rest:
intercept:
enabled: true
這樣所有的服務都具備了版本屬性
然後在使用請求的時候,請求的Header中傳入 n-d-version來進行路由規劃,配置方式有2種:
第一種方式是直接填寫版本號,例如 n-d-version: 1.0 或者 n-d-version: 2.0 則整個調用鏈路,都會使用1.0或者使用2.0來進行
如果服務間存在調用關係,使用的Feign調用,則A服務1.0調用B服務1.0 或者 A服務的2.0調用B服務的2.0
第二種方式是填寫版本調用關係,例如n-d-version:{"example-server-a":"1.0","example-server-a":"2.0"},這樣的一個JSON串標識的含義是 A服務的1.0調用B服務的2.0。n-d-version:{"example-server-a":"1.0","example-server-a":"1.0;2.0"},代表A服務1.0調用B服務的1.0或者2.0,B服務是輪訓負載調用,此時如果B服務的2.0下線,則A服務會每次調用B服務的1.0,只是要注意一個現象,如果沒有完全下線完畢,註冊中心還有而服務不可用,則負載到B服務的2.0時候會有超時,但是過後還是會調用到1.0服務上返回結果,因爲註冊中心很快會下線,這種情況一般來說比較短暫。
以上這種場景比較適合小程序的前端發佈,例如微信小程序一般會有一個發佈上線審覈的過程,審覈期間可以發佈對應的新版本服務用於微信官方審覈,待審覈發佈通過後,老版本服務下線。最終實現基於灰度策略的路由。