基於Spring cloud ribbon實現灰度發佈

在上一篇文章《基於Spring cloud ribbon實現多版本控制》中介紹瞭如何擴展spring cloud ribbon實現接口多版本控制的項目 – fm-cloud-bambbo, 開發這個項目的過程,給我提供了很多想法和思路,發現只要再做一些擴展,就可以實現灰度管理,於是又有了 fm-cloud-graybunny。

灰度發佈

灰度發佈是在多版本控制的基礎上進一步擴展實現出來的項目 -> fm-cloud-graybunny,抽象出灰度服務、灰度服務實例、灰度策略、灰度決策等。支持A/B test, 金絲雀 test。 灰度策略可以從request ip, request patameter, request header等方面進行去創建,也可以根據bamboo的LoadBalanceRequestTrigger結合graybuanny的接口去擴展灰度策略和灰度決策。

場景

有兩個服務,共四個服務實例,分別是ServiceA-1, ServiceA-2, ServiceB-1。其中ServiceA-2是灰度實例。

  • 場景1
    所有請求頭usertype:old,ip:10.217..的請求或者請求頭usertype:test, url 參數action:create的請求,都會被轉發到的灰度服務ServiceA-2 。

  • 場景2
    ServiceA-2通過一段時間的觀察,判定運行穩定,開始ServiceA-2刪除灰度標記,開始和ServiceA-1一樣會加入正常的負載均衡規則當中。

  • 場景3
    服務ServiceB發佈新版本,ServiceB-2需要灰度註冊,註冊成功後所有的請求不能轉發到ServiceB-2, 在爲ServiceB-2設置灰度策略後,符合策略的請求才會被轉發到ServiceB-2上。

思路

從上面的場景分析,可以歸納出兩個對象:服務實例和調用請求;服務實例的灰度管理是基礎,調用請求時如何決策路由,都是根據服務實例的灰度策略去判斷的。既然有灰度管理這個概念,那麼從功能上分,就會有client-server之分,所以又可以從graybunny-client和graybunny-server去分析。接下來將一步一步去分析這四個方面。

灰度實例

這裏寫圖片描述

  • 實例註冊
    服務實例添加到灰度管理中。

  • 實例下線
    服務實例下線,從灰度管理中刪除。

  • 灰度開關
    調整服務實例的灰度狀態,有啓用、禁用兩個狀態,禁用的實例不納入灰度列表中。

  • 灰度策略
    請求是否可以被轉發到該服務實例的條件,只有通過,請求才有可能會被轉發到該實例上。

調用請求

這裏寫圖片描述

  • 灰度決策
    根據請求的信息去匹配灰度服務實例的灰度策略,如果匹配上,會將服務實例加入到通過列表中。如果都沒有匹配上,就按bamboo的路由規則去篩選非灰度的服務實例進行轉發。
灰度客戶端

調用請求的服務消費者,和提供服務的服務提供者都可以是灰度客戶端,因爲微服務中,大多服務實例既是服務提供者,同時也是服務消費者。
這裏寫圖片描述

  • 灰度服務註冊
    服務實例在啓動時,就會向灰度服務端發起請求,將實例自身的灰度開關打開。

  • 灰度服務下線
    在服務實例下線前,會觸發鉤子,向灰度服務端發起請求將實例自身從灰度列表中刪除。

  • 接收灰度實例調整消息
    接收由灰度服務端推送過來的灰度列表更新消息比如新增灰度實例,刪除灰度實例等,維護緩存在實例上的灰度列表。

  • 定時拉取灰度列表
    定時從灰度服務端拉取最新的灰度列表,維護實例自身緩存的灰度列表。

灰度服務端

灰度服務端負表維護灰度列表,可以新增、刪除、編輯灰度信息。
這裏寫圖片描述

  • 編輯灰度實例
    新增灰度實例,刪除灰度實例,修改實例灰度狀態。

  • 編輯灰度策略
    新增實例灰度策略,刪除實例灰度策略,修改灰度策略狀態。

  • 推送灰度服務調整消息
    向灰度客戶端推送灰度列表變動消息,比如新增灰度實例,刪除灰度實例,修改實例灰度狀態等。

  • 定時檢查服務實例是否下線
    定時檢查灰度服務實例是否下線,下線的的實例將從灰度列表中刪除。

代碼設計

根據上面的思路,設計以下對象和接口。共6個接口,4個模型對象。
這裏寫圖片描述

對象:

  • GrayService
    灰度服務

  • GrayInstance
    灰度實例,有狀態屬性

  • GrayPolicyGroup
    灰度策略組,有狀態屬性

  • GrayPolicy
    灰度策略

接口:

  • GrayManager
    灰度客戶端管理器,維護灰度列表,維護自身灰度狀態,創建灰度決策對象。抽象實現類AbstractGrayManager實現了基礎的獲取灰度列表, 創建灰度決策對象的能力。BaseGrayManger在期基礎上進行了擴展,將灰度列表緩存起來,定時從灰度服務端更新灰度列表。

  • InformationClient
    該接口主要是負責和灰度服務端進行通信,獲取灰度列表,編輯灰度實例等能力。其實現類HttpInformationClient默認使用http方式訪問灰度服務端。
    子類InformationClientDecorator是一個適配器類,RetryableInformationClient繼承了InformationClientDecorator類,實現了重試的功能。

  • GrayDecision
    該接口是灰度決策,用來判斷請求是否匹配灰度策略。實現了ip匹配、request parameter匹配、request header匹配、BambooRequestContext中的參數匹配器以及合併匹配等多個匹配能力。

  • GrayDecisionFactory
    灰度決策的工廠類,其默認實現類支持上述幾種灰度決策的創建。

  • GrayServiceManager
    灰度服務管理類,屬於服務端的類。主要是編輯服務實例,編輯灰度策略,以及維護最新的灰度列表。

  • GrayBunnyServerEvictor
    如果灰度服務實例下線後, 由於意外情況,沒有向灰度服務端發送刪除請求, 服務端會每隔一段時間調用該接口的方法,檢查灰度列表中的實例是否下線,如果實例已下線,就將其從灰度列表中刪除。

代碼實現

將模型抽象成接口和對象設計出來之後,實現思路就清晰了。

  • 灰度路由
    灰度路由是客戶端必須要實現的能力,graybunny是在bamboo的基礎上擴展的,所以graybunny的路由規則對象GrayLoadBalanceRule繼承了BambooZoneAvoidanceRule,
    邏輯是這樣的:
    1、 判斷目標服務是否有灰度實例。
    2.1、 如果沒有, 執行父類邏輯。結束。
    2.2、 有灰度實例,先將灰度實例和非灰度實例篩選出來。
    3、 挑選灰度實例, 篩選調用請求匹配上灰度實例的策略。
    4.1、 如果沒有匹配的灰度實例, 將非灰度實例列表傳遞過去執行父類的篩選邏輯。結束。
    4.2、 如果有匹配的灰度實例, 從其中按輪詢的方式挑選出一個實例。結束。
    這裏寫圖片描述
    灰度決策的執行代碼在GrayDecisionPredicate中
    這裏寫圖片描述

  • 灰度管理
    灰度管理是灰度服務端的功能,主要是維護灰度列表。其實現類DefaultGrayServiceManger有一個Map, 用來維護GrayService,key是service id。並且每隔一段時間就調用EurekaGrayBunnyServerEvictor,檢查列表中的實例是否下線,將下線的服務從灰度列表中刪除。
    這裏寫圖片描述
    EurekaGrayBunnyServerEvictor是依賴EurekaClient來檢查服務實例是否下線。
    這裏寫圖片描述

使用指導

灰度管理的配置和bamboo的配置是一樣的, 配置方式差別不大。下面先說gray-server的配置。

Gray-Server:
在項目的pom.xml加入spring-boot相關的依賴,再加入bamboo-start、graybunny-server-starter,然後啓動就可以了。
這裏寫圖片描述

在啓動類中,需要僱用服務發現。
這裏寫圖片描述

啓動後,可以訪問http://localhost:10202/swagger-ui.html#/service-gray-resouce查看接口列表,也可以調用其中的接口。

這裏寫圖片描述

以上介紹完了gray-server的配置,下面再看gray-client的配置。

Gray-Client

  1. 在pom.xml中加入gm-cloud-graybunny。
    這裏寫圖片描述

  2. 在application.yaml中加入灰度配置。
    這裏寫圖片描述

  3. 在啓動類中加入灰度客戶端的註解@EnableGrayBunny
    這裏寫圖片描述

這樣灰略度的服務端和客戶端都配置好了, 只要在灰度服務端開啓灰度實例和灰度策,在灰度客戶端就會自動進行灰度路由。

項目地址

https://github.com/saleson/fm-cloud/tree/master/fm-cloud/fm-cloud-plugins/fm-cloud-graybunny

不足

graybunny目前只有灰度管理的基本功能, 像數據持久化,高可用,推送灰度調整消息等, 都沒有實現。 也沒有界面化, 僅僅只有接口列表。

擴展思考

graybunny目前僅僅只支持spring cloud eureka, 但是在spring cloud中,eureka只是做爲其中一個註冊中心, 如果要做spring cloud的灰度管理, 就還需要兼容其中的註冊中心, 比如zookeeper, consul等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章