深入理解Apollo核心機制之配置讀取——輪詢

前兩篇內容
深入理解Apollo核心機制之配置讀取——前言
深入理解Apollo核心機制之配置讀取——ConfigService定時掃描

概述

讀取配置除了默認5分鐘間隔去輪詢接口拉取配置,還有客戶端主動長輪詢ConfigService,等待通知後主動拉取配置。本文就看看客戶端是如何開始客戶端輪詢的,以及輪詢中的具體細節。

RemoteConfigRepository#RemoteConfigRepository(String namespace) 初始化工作

該構造函數會初始化命名空間,配置緩存等許多基本信息,同時有一步就是將自己(this)註冊進RemoteConfigLongPollService,因爲後續長輪詢其實是該Service統一去做的。

RemoteConfigRepository#scheduleLongPollingRefresh() 註冊接口

m_namespace是在初始話的時候設置的,它表示該Repository所對應的命名空間。

RemoteConfigLongPollService#submit(String namespace, RemoteConfigRepository remoteConfigRepository) 正式註冊並開始開啓長輪詢準備工作

RemoteConfigLongPollService#startLongPolling() 準備正式開啓長輪詢

RemoteConfigLongPollService#doLongPollingRefresh(String appId,String cluster,String dataCenter) 長輪詢開始

通過封裝了Eureka的MetaService獲取ConfigService集羣,然後硬核負載均衡打到ConfigService的長輪詢接口開始長輪詢等待通知,如果關注的namespace有更新,則會做一些更新本地成員變量的操作,最重要的就是會通知相關的註冊進來的Repository去主動拉取配置。這就是客戶端長輪詢等待通知,發現有配置更新後主動去拉取配置的一個基本流程。注意,當發送請求到長輪詢接口的時候會被ConfigService hold住,直到響應或者超時。稍後再看NotificationControllerV2那邊的流程。我們先關注客戶端長輪詢、獲取通知、主動輪詢拉取配置接口的過程。

RemoteConfigLongPollService#notify(ServiceDTO lastServiceDTO, List notifications) 長輪詢結果通知客戶端

根據通知中傳遞的namespaceName,去之前註冊的Repository集合Map拿到關注該namespaceName的Repository

RemoteConfigRepository#onLongPollNotified(ServiceDTO longPollNotifiedServiceDto, ApolloNotificationMessages remoteMessages) 準備同步配置

AbstractConfigRepository#trySync() 準備同步配置

緩存中拿一份,遠程拉取一份,比較後更新內存緩存。並通知

RemoteConfigRepository#loadApolloConfig() 拉取配置

拼接URL請求ConfigService接口拉取配置

AbstractConfigRepository#fireRepositoryChange(String namespace, Properties newProperties) 通知監聽器配置改變(實時修改配置)

回到長輪詢,話說客戶端拼接請求打到ConfigService的NotificationControllerV2#pollNotification接口後是什麼情況呢?

NotificationControllerV2#pollNotification 拉取(等待)通知

有一個Multimap<String,DeferredResultWrapper>,以key(appId+cluster+namespace)和List存儲watchKey和客戶端的關係。
每一次請求,都會創建一個DeferredResultWrapper,然後通過一系列操作最後將自己註冊進上述集合,等待handleMessage調用setResult(結束長輪詢)或者超時,這樣就把Result返回給客戶端了。
客戶端就可以獲得變更通知從而知道是什麼namespace變更了,然後會主動拉取對應配置。

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