天天看點

Soul網關源碼分析-12期(周總結)HTTP 服務探活

文章目錄

  • HTTP 服務探活
    • 服務注冊
      • 背景緩存資訊新增
      • 背景緩存資訊新增 通知網關
      • 網關緩存資訊新增
    • 服務下線
      • 背景緩存資訊變動
      • 背景緩存資訊變動 通知網關
      • 網關緩存資訊更新
    • TIPS
    • 總結

HTTP 服務探活

目的

最終目的是搞清楚網關中服務節點緩存在各種情況下的變動, 這樣在請求網關轉發 HTTP 服務時, 才能做到心中有數.

拆分任務

看到最終目的, 我會有幾個想法:

  1. 網關的緩存節點資訊應該在何時變動 ?
  2. 背景資料會同步網關, 那背景資料如何變動, 如何通知網關 ?

根據這些問題, 就得到了要進行的任務 ==>

  • HTTP 服務注冊時
    • 背景緩存的服務節點如何變動
    • 背景緩存加入新注冊資訊後, 如何通知網關
    • 網關如何新增服務緩存
  • HTTP 服務下線時 (探活)
    • 背景如何得知服務下線并更新緩存
    • 背景緩存更新後, 如何通知網關
    • 網關如何更新服務緩存

服務注冊

背景緩存資訊新增

UpstreamCheckService 的 UPSTREAM_MAP 中存放着背景服務節點資訊

public class UpstreamCheckService {
  
	private static final Map<String, List<DivideUpstream>> UPSTREAM_MAP = Maps.newConcurrentMap();
}
           

UPSTREAM_MAP 中的資料有兩個來源, 一是啟動時從資料庫拿, 二是服務注冊時傳入.

資料庫擷取方式相對簡單, 在 UpstreamCheckService#setup 中有展現.

服務注冊路徑圖:

SpringMvcClientBeanPostProcessor(http服務端): 收集Controller層資訊, 請求背景的路徑:

/soul-client/springmvc-register

SoulController: 背景對外暴露的 Http api, 供請求服務注冊

SoulClientRegisterServiceImpl: 直接調用 UpstreamCheckService#submit 傳入要新增的節點資料

背景緩存資訊新增 通知網關

背景通知路徑圖 (Websocket模式):

SoulClientRegisterServiceImpl: 發送自定義事件, 由訂閱事件中心處理 (Spring 釋出訂閱模式)

DataChangedEventDispatcher: 事件接收和分發類, 根據事件類型調用監聽類的對應方法

WebsocketCollector: 管理 Websocket 通信, 維護連接配接的 session 會話.

網關緩存資訊新增

UpstreamCheckService 的 UPSTREAM_MAP 中存放着網關的 divide 插件服務節點資訊

public final class UpstreamCacheManager {
    
  private static final Map<String, List<DivideUpstream>> UPSTREAM_MAP = Maps.newConcurrentMap();
}
           

服務資訊變動路徑圖 (Websocket模式):

SoulWebsocketClient: 背景 wesocket 資訊在這裡被監聽, 并發送給 WebsocketDataHandler 處理.

WebsocketDataHandler: 根據事件類型, 選擇對應處理器 (PluginDataHandler、RuleDataHandler等)

AbstractDataHandler: 根據事件變動類型(refresh、update等), 調用處理器對應方法, 具體實作類會調用到 CommonPluginDataSubscriber 訂閱器

CommonPluginDataSubscriber: 這裡存有所有注冊為 Bean 的事件處理器, 這些處理器來自各個擴充插件, 會調用他們的 handlerXXX() 方法

DividePluginDataHandler: 更新或移除緩存管理器中服務節點資訊

服務下線

背景緩存資訊變動

探活路徑圖:

背景緩存管理器在初始化時, 會啟動定時器 (間隔10秒) 檢測緩存中節點服務的活性, 方式是嘗試 Socket#connect 連接配接.

背景緩存資訊變動 通知網關

通知路徑圖 (Websocket模式):

這塊與 HTTP 服務注冊時背景通知網關很相似, 最終都會流入到 DataChangedEventDispatcher 事件分發器, 并通過 Websocket 通信發出.

不同的是發起點, HTTP 服務注冊時, 由具體的 HTTP 服務發起背景請求, 而 HTTP 服務下線時, 是由背景緩存管理器自身的定時探活子產品發起.

網關緩存資訊更新

網關的緩存更新有兩種方式, 一個是接收到背景資訊變更通知, 這點與服務注冊時一緻, 不再贅述.

第二種是 divide 的緩存管理器, 可開啟如同背景的定時探活, 也是通過 Socket#connect 去判斷服務是否可用, 但這塊預設配置是關閉的, 且檢測間隔時間為 30S.

TIPS

HTTP 服務注冊時, 背景會将服務資訊寫入資料庫.

public class SoulClientRegisterServiceImpl implements SoulClientRegisterService {
  
  private String registerSelector(final String contextPath, final String rpcType, final String appName, final String uri) {
    // ...
    if (RpcTypeEnum.DUBBO.getName().equals(rpcType)) {

    } else {
      //... is divide
      // 通知緩存管理器節點資訊
      upstreamCheckService.submit(selectorDTO.getName(), divideUpstream);
    }
    // ...
    // 這裡會将資料寫入資料庫
    return selectorService.register(selectorDTO);
  }
}
           

總結

引用 “進擊的巨人” 裡常看見的一句話, 根據現在可以公開的情報:

  • 背景的 UpstreamCheckService 類以及網關的 UpstreamCacheManager 類持有各自的服務節點緩存資訊
  • UpstreamCheckService -> UpstreamCacheManager 可以通過架構提供的資料同步傳輸 (Websocket、Zookeeper 等)
  • 背景HTTP服務的探活是定時嘗試 Socket 連接配接來完成, 而網關端可以接收到背景資料同步來的最新資訊, 不用自己完成探活
  • 網關有可選項, 開啟定時 Socket 連接配接完成探活 (肯定是不建議開的, 網關太累了…)

一點思考🤔 : Socket 連接配接有些過重, 改進的話參考一些注冊中心的實作, 比如 Eureka 會讓服務節點引入 EurekaClient , 與服務端 EurekaServer 做心跳檢測, 是一種比較輕的探活方式.