极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)
本篇將重點(diǎn)關(guān)注 Sentienl 實(shí)時(shí)數(shù)據(jù)收集,即 Sentienl 具體是如何收集調(diào)用信息,以此來(lái)判斷是否需要觸發(fā)限流或熔斷。
Sentienl 實(shí)時(shí)數(shù)據(jù)收集的入口類(lèi)為 StatisticSlot。
我們先簡(jiǎn)單來(lái)看一下 StatisticSlot 該類(lèi)的注釋,來(lái)看一下該類(lèi)的整體定位。
StatisticSlot,專(zhuān)用于實(shí)時(shí)統(tǒng)計(jì)的 slot。在進(jìn)入一個(gè)資源時(shí),在執(zhí)行 Sentienl 的處理鏈條中會(huì)進(jìn)入到該 slot 中,需要完成如下計(jì)算任務(wù):
- 集群維度計(jì)算資源的總統(tǒng)計(jì)信息,用于集群限流,后續(xù)文章將詳細(xì)探討。
- 來(lái)自不同調(diào)用方/來(lái)源的群集節(jié)點(diǎn)的統(tǒng)計(jì)信息。
- 特定調(diào)用上下文環(huán)境的統(tǒng)計(jì)信息。
- 統(tǒng)計(jì)所有入口的統(tǒng)計(jì)信息。
接下來(lái)用源碼分析的手段來(lái)詳細(xì)分析 StatisticSlot 的實(shí)現(xiàn)原理。
1、源碼分析 StatisticSlot
1.1 StatisticSlot entry 詳解
StatisticSlot#entry
StatisticSlot#entry
StatisticSlot#entry
StatisticSlot#entry
代碼@1:首先調(diào)用 fireEntry,先調(diào)用 Sentinel Slot Chain 中其他的處理器,執(zhí)行完其他處理器的邏輯,例如 FlowSlot、DegradeSlot,因?yàn)?StatisticSlot 的職責(zé)是收集統(tǒng)計(jì)信息。
代碼@2:如果后續(xù)處理器成功執(zhí)行,則將正在執(zhí)行線(xiàn)程數(shù)統(tǒng)計(jì)指標(biāo)加一,并將通過(guò)的請(qǐng)求數(shù)量指標(biāo)增加對(duì)應(yīng)的值。下文會(huì)對(duì) Sentinel Node 體系進(jìn)行詳細(xì)的介紹,在 Sentinel 中使用 Node 來(lái)表示調(diào)用鏈中的某一個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)關(guān)聯(lián)一個(gè)資源,資源的實(shí)時(shí)統(tǒng)計(jì)信息就存儲(chǔ)在 Node 中,故該部分也是調(diào)用 DefaultNode 的相關(guān)方法來(lái)改變線(xiàn)程數(shù)等,將在下文會(huì)向詳細(xì)介紹。
代碼@3:如果上下文環(huán)境中保存了調(diào)用的源頭(調(diào)用方)的節(jié)點(diǎn)信息不為空,則更新該節(jié)點(diǎn)的統(tǒng)計(jì)數(shù)據(jù):線(xiàn)程數(shù)與通過(guò)數(shù)量。
代碼@4:如果資源的進(jìn)入類(lèi)型為 EntryType.IN,表示入站流量,更新入站全局統(tǒng)計(jì)數(shù)據(jù)(集群范圍 ClusterNode)。
代碼@5:執(zhí)行注冊(cè)的進(jìn)入Handler,可以通過(guò) StatisticSlotCallbackRegistry 的 addEntryCallback 注冊(cè)相關(guān)監(jiān)聽(tīng)器。
代碼@6:如果捕獲到 PriorityWaitException ,則認(rèn)為是等待過(guò)一定時(shí)間,但最終還是算通過(guò),只需增加線(xiàn)程的個(gè)數(shù),但無(wú)需增加節(jié)點(diǎn)通過(guò)的數(shù)量,具體原因我們?cè)谠敿?xì)分析限流部分時(shí)會(huì)重點(diǎn)討論,也會(huì)再次闡述 PriorityWaitException 的含義。
代碼@7:如果捕獲到 BlockException,則主要增加阻塞的數(shù)量。
代碼@8:如果是系統(tǒng)異常,則增加異常數(shù)量。
我想上面的代碼應(yīng)該不難理解,但涉及到統(tǒng)計(jì)指標(biāo)數(shù)據(jù)的變化,都是調(diào)用 DefaultNode node 相關(guān)的方法,從這里也可以看出,Node 將是實(shí)時(shí)統(tǒng)計(jì)數(shù)據(jù)的直接持有者,那毋容置疑接下來(lái)將重點(diǎn)來(lái)學(xué)習(xí) Node,為了知識(shí)體系的完備性,我們先來(lái)看一下 StatisticSlot 的 exit 方法。
1.2 StatisticSlot exit 詳解
StatisticSlot#exit
代碼@1:成功執(zhí)行,則重點(diǎn)關(guān)注響應(yīng)時(shí)間,其實(shí)現(xiàn)亮點(diǎn)如下:
- 計(jì)算本次響應(yīng)時(shí)間,將本次響應(yīng)時(shí)間收集到 Node 中。
- 將當(dāng)前活躍線(xiàn)程數(shù)減一。
代碼@2:執(zhí)行退出時(shí)的 callback。可以通過(guò) StatisticSlotCallbackRegistry 的 addExitCallback 方法添加退出回調(diào)函數(shù)。
代碼@3:傳播 exit 事件。
接下來(lái)我們將重點(diǎn)介紹 DefaultNode,即 Sentinel 的 Node 體系,持有資源的實(shí)時(shí)調(diào)用信息。
2、Sentienl Node 體系
2.1 Node 類(lèi)體系圖
我們先簡(jiǎn)單介紹一下上述核心類(lèi)的作用與核心接口或核心屬性的含義。
- OccupySupport
支持搶占未來(lái)的時(shí)間窗口,有點(diǎn)類(lèi)似借用“未來(lái)”的令牌。其核心方法如下:
1)long tryOccupyNext(long currentTime, int acquireCount, double threshold)
嘗試搶占未來(lái)的令牌,返回值為調(diào)用該方法的線(xiàn)程應(yīng)該 sleep 的時(shí)間。
1、long currentTime
當(dāng)前時(shí)間。
2、int acquireCount
本次需要申請(qǐng)的令牌個(gè)數(shù)。
3、double threshold
設(shè)置的闊值。
2)long waiting()
獲取當(dāng)前已申請(qǐng)的未來(lái)的令牌的個(gè)數(shù)。
3)void addWaitingRequest(long futureTime, int acquireCount)
申請(qǐng)未來(lái)時(shí)間窗口中的令牌。
4)void addOccupiedPass(int acquireCount)
增加申請(qǐng)未來(lái)令牌通過(guò)的個(gè)數(shù)。
5)double occupiedPassQps()
當(dāng)前搶占未來(lái)令牌的QPS。
- Node
持有實(shí)時(shí)統(tǒng)計(jì)信息的節(jié)點(diǎn)。定義了收集統(tǒng)計(jì)信息與獲取統(tǒng)計(jì)信息的接口,上面方法根據(jù)方法名稱(chēng)即可得知其含義,故這里就不一一羅列了。
- StatisticNode
實(shí)現(xiàn)統(tǒng)計(jì)信息的默認(rèn)實(shí)現(xiàn)類(lèi)。
- DefaultNode
用于在特定上下文環(huán)境中保存某一個(gè)資源的實(shí)時(shí)統(tǒng)計(jì)信息。
- ClusterNode
實(shí)現(xiàn)基于集群限流模式的節(jié)點(diǎn),將在集群限流模式部分詳細(xì)介紹。
- EntranceNode
用來(lái)表示調(diào)用鏈入口的節(jié)點(diǎn)信息。
本文將詳細(xì)介紹 DefaultNode 與 StatisticNode,重點(diǎn)闡述調(diào)用樹(shù)與實(shí)時(shí)統(tǒng)計(jì)信息。DefaultNode 是 StatisticNode 的子類(lèi),我們先從 StatisticNode 開(kāi)始 Node 體系的探究。
3、StatisticNode 詳解
3.1 核心類(lèi)圖
我們對(duì)其核心屬性進(jìn)行一一解讀:
- Metric rollingCounterInSecond = new ArrayMetric(SampleCountProperty.SAMPLE_COUNT, IntervalProperty.INTERVAL)
每秒的實(shí)時(shí)統(tǒng)計(jì)信息,使用 ArrayMetric 實(shí)現(xiàn),即基于滑動(dòng)窗口實(shí)現(xiàn),正是上篇文章詳細(xì)介紹的,默認(rèn)1s 采樣 2次。即一個(gè)統(tǒng)計(jì)周期中包含兩個(gè)滑動(dòng)窗口。
- Metric rollingCounterInMinute = new ArrayMetric(60, 60 * 1000, false)
每分鐘實(shí)時(shí)統(tǒng)計(jì)信息,同樣使用 ArrayMetric 實(shí)現(xiàn),即基于滑動(dòng)窗口實(shí)現(xiàn)。每1分鐘,抽樣60次,即包含60個(gè)滑動(dòng)窗口,每一個(gè)窗口的時(shí)間間隔為 1s 。
- LongAdder curThreadNum = new LongAdder()
當(dāng)前線(xiàn)程計(jì)數(shù)器。
- long lastFetchTime = -1
上一次獲取資源的有效統(tǒng)計(jì)數(shù)據(jù)的時(shí)間,即調(diào)用 Node 的 metrics() 方法的時(shí)間。
關(guān)于 ArrayMetric 滑動(dòng)窗口設(shè)計(jì)與實(shí)現(xiàn)原理,請(qǐng)參考筆者的另一篇博文:源碼分析 Alibaba sentinel 滑動(dòng)窗口實(shí)現(xiàn)原理(文末附原理圖)
接下來(lái)我們挑選幾個(gè)具有代表性的方法進(jìn)行探究。
2.2 addPassRequest
增加通過(guò)請(qǐng)求數(shù)量。即將實(shí)時(shí)調(diào)用信息向滑動(dòng)窗口中進(jìn)行統(tǒng)計(jì)。addPassRequest 即報(bào)告成功的通過(guò)數(shù)量。就是分別調(diào)用 秒級(jí)、分鐘即對(duì)應(yīng)的滑動(dòng)窗口中添加數(shù)量,然后限流規(guī)則、熔斷規(guī)則將基于滑動(dòng)窗口中的值進(jìn)行計(jì)算。
2.3 totalRequest
獲取當(dāng)前時(shí)間戳的總請(qǐng)求數(shù),獲取分鐘級(jí)時(shí)間窗口中的統(tǒng)計(jì)信息。
2.4 successQps
成功TPS,用秒級(jí)統(tǒng)計(jì)滑動(dòng)窗口中統(tǒng)計(jì)的個(gè)數(shù) 除以 窗口的間隔得出其 tps,即抽樣個(gè)數(shù)越大,其統(tǒng)計(jì)越精確。
溫馨提示:上面的方法在學(xué)習(xí)了上文的滑動(dòng)窗口設(shè)計(jì)原理后將顯得非常簡(jiǎn)單,大家在學(xué)習(xí)的過(guò)程中,可以總結(jié)出一個(gè)規(guī)律,什么時(shí)候時(shí)候使用秒級(jí)滑動(dòng)窗口,什么時(shí)候使用分鐘級(jí)滑動(dòng)窗口。
2.5 metrics
由于 Sentienl 基于滑動(dòng)窗口來(lái)實(shí)時(shí)收集統(tǒng)計(jì)信息,并存儲(chǔ)在內(nèi)存中,并隨著時(shí)間的推移,舊的滑動(dòng)窗口將失效,故需要提供一個(gè)方法,及時(shí)將所有的統(tǒng)計(jì)信息進(jìn)行匯總輸出,供監(jiān)控客戶(hù)端定時(shí)拉取,轉(zhuǎn)儲(chǔ)都其他客戶(hù)端,例如數(shù)據(jù)庫(kù),方便監(jiān)控?cái)?shù)據(jù)的可視化,這也通常是中間件用于監(jiān)控指標(biāo)的監(jiān)控與采集的通用設(shè)計(jì)方法。
代碼@1:獲取當(dāng)前時(shí)間對(duì)應(yīng)的滑動(dòng)窗口的開(kāi)始時(shí)間,可以對(duì)比上文計(jì)算滑動(dòng)窗口的算法。
代碼@2:獲取一分鐘內(nèi)的所有滑動(dòng)窗口中的統(tǒng)計(jì)數(shù)據(jù),使用 MetricNode 表示。
代碼@3:遍歷所有節(jié)點(diǎn),刷選出不是當(dāng)前滑動(dòng)窗口外的所有數(shù)據(jù)。這里的重點(diǎn)是方法:isNodeInTime。
這里只刷選出不是當(dāng)前窗口的數(shù)據(jù),即 metrics 方法返回的是“過(guò)去”的統(tǒng)計(jì)數(shù)據(jù)。
接下來(lái)我們?cè)賮?lái)看看 DefaultNode 相關(guān)的幾個(gè)特性方法。
4、DefaultNode 詳解
4.1 類(lèi)圖
DefaultNode 是 StatisticNode 的子類(lèi),其額外增加的屬性如下:
- private ResourceWrapper id
資源id,即 DefaultNode 才真正與資源掛鉤,可以將 DefaultNode 看出是調(diào)用鏈中的一個(gè)節(jié)點(diǎn),并且與資源關(guān)聯(lián)。
- private volatile Set< Node > childList
子節(jié)點(diǎn)結(jié)合。以此來(lái)維持其調(diào)用鏈。
- private ClusterNode clusterNode
集群節(jié)點(diǎn),同樣為 StatisticNode 的子類(lèi),表示與資源集群相關(guān)的環(huán)境。
接下來(lái)我們將來(lái)看一下 DefaultNode 的核心方法。
4.2 increaseBlockQps
DefaultNode 的此類(lèi)方法,通常是先調(diào)用 StatisticNode 的方法,然后再調(diào)用 clusterNode 的相關(guān)方法,最終就是使用在對(duì)應(yīng)的滑動(dòng)窗口中增加或減少計(jì)量值。
其他方法也比較簡(jiǎn)單,就不再細(xì)看了,我們可以通過(guò) DefaultNode 的 printDefaultNode 方法來(lái)打印該節(jié)點(diǎn)的調(diào)用鏈。
本文就介紹到這里了,本文詳細(xì)介紹了 Sentinel 實(shí)時(shí)數(shù)據(jù)收集的統(tǒng)一入口 StatisticSlot,并且介紹了 Seninel Node 體系,即調(diào)用鏈中的每一個(gè)節(jié)點(diǎn),每一個(gè)節(jié)點(diǎn)對(duì)一個(gè)資源的實(shí)時(shí)統(tǒng)計(jì)信息。下一篇將開(kāi)始重點(diǎn)限流是如何實(shí)現(xiàn)的,即 FlowSlot 的實(shí)現(xiàn)技巧。
源碼分析 Sentinel 系列專(zhuān)欄連載中,已發(fā)表目錄:
1、Sentinel 限流與熔斷初探(技巧篇)
2、滑動(dòng)窗口實(shí)現(xiàn)原理(文末附原理圖)
3、尋找一把 Sentinel 的鑰匙
4、調(diào)用上下文環(huán)境實(shí)現(xiàn)原理(圖文并茂)
總結(jié)
以上是生活随笔為你收集整理的极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: session mysql java_P
- 下一篇: 升级步骤linux_开发人员福音,在wi