概述
之前我們瞭解了,客戶端會每秒(默認)長輪詢Config Service,等待通知,然後去主動拉取配置文件。本文主要跟進Config Service主動輪詢ReleaseMessage表,並通知對應監聽器的源碼,最終終止客戶端長輪詢的源碼。附上之前的鏈接《深入理解Apollo核心機制之配置讀取——前言》
監聽器介紹
Config Service中有一些類實現了ReleaseMessageListener接口,並重寫了handleMessage()方法,當ConfigService掃描到有新的配置發佈的時候,就會輪詢通知所有實現了上述監聽器接口的監聽器,調用handleMessage()方法。我們要了解的和客戶端長輪詢的監聽器的類便是NotificationControllerV2。其它的監聽器在配置發佈的時候也有自己的職責,這裏不過多介紹,我們只會查看NotificationControllerV2中的handleMessage()方法,瞭解它在接到通知的時候是如何處理消息的。
監聽器註冊
監聽器結構
ReleaseMessageScanner#afterPropertiesSet() 開啓掃描任務
首先看到ReleaseMessageScanner類,這個類就是做這件事情的。我們會發現它會開啓一個定時掃描的任務(默認1秒間隔),具體看下面源碼。
ReleaseMessageScanner#scanMessages() 掃描條件
ReleaseMessageScanner#scanAndSendMessages() 掃描併發送通知
Config Service會查出”當前最大掃描ID“後500條數據(根據ID升序),如果沒有數據,則代表上次掃描之後,沒有新的配置發佈,如果有新的配置發佈則會通知監聽器。
必備Tip
客戶端發起長輪詢是請求NotificationControllerV2的pollNotification接口,經過一系列處理,會將請求的客戶端保存下來。(Map形式,key爲"{appId}+{clusterName}+{namespaceName}",value爲List
下圖代碼便是該監聽器的handleMessage()源碼了,它會根據收到的”message",提取appId、clusterName、namespaceName,輪詢通知根據key得到的DeferredResultWrapper集合(調用setResult()方法)。從而將通知信息(DeferredResult<ResponseEntity<List