文章目錄
- HTTP 服務探活
-
- 服務注冊
-
- 背景緩存資訊新增
- 背景緩存資訊新增 通知網關
- 網關緩存資訊新增
- 服務下線
-
- 背景緩存資訊變動
- 背景緩存資訊變動 通知網關
- 網關緩存資訊更新
- TIPS
- 總結
HTTP 服務探活
目的
最終目的是搞清楚網關中服務節點緩存在各種情況下的變動, 這樣在請求網關轉發 HTTP 服務時, 才能做到心中有數.
拆分任務
看到最終目的, 我會有幾個想法:
- 網關的緩存節點資訊應該在何時變動 ?
- 背景資料會同步網關, 那背景資料如何變動, 如何通知網關 ?
根據這些問題, 就得到了要進行的任務 ==>
- 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 做心跳檢測, 是一種比較輕的探活方式.