天天看點

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

作者:程式員進階碼農II

Sentinel的整體工作流程分析

如果不借助Sentinel提供的适配子產品,則可以采用下面的方法使用Sentinel,代碼如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

① 調用ContextUtil#enter方法。

② 調用SphU#entry方法,該方法會為資源建立Entry執行個體。

③ 若抛出異常,且非BlockException異常,則調用Tracer#trace方法統計異常。

④ 調用資源的Entry#exit方法。

⑤ 調用ContextUtil#exit方法。

1. ContextUtil#enter方法

ContextUtil#enter方法負責在調用鍊入口建立Context執行個體,以及為調用鍊建立入口節點,即EntranceNode執行個體,源碼如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

① ContextUtil使用ThreadLocal存儲Context,若目前調用鍊上已經存在Context,則使用已經存在的Context,否則建立Context。

② 嘗試從緩存中擷取已經存在的入口節點。

③ 若不存在入口節點,則建立入口節點,入口節點的名稱與Context的名稱相同。

④ 将入口節點添加到調用樹的ROOT節點的子節點中。

入口節點是一個調用鍊入口,隻能被建立一個,并且作為調用樹根節點(ROOT)的子節點。

2. SphU#entry方法

Sentinel的核心骨架是ProcessorSlotChain,是以核心的流程是一次SphU#entry方法的調用及一次Entry#exit方法的調用。

SphU#entry方法會調用CtSph#entry方法。CtSph的作用如下:為資源建立ResourceWrapper對象并為資源構造一個全局唯一的ProcessorSlotChain,為資源建立CtEntry并将CtEntry指派給目前調用鍊上下文的curEntry字段,調用ProcessorSlotChain#entry方法完成一次ProcessorSlot單向連結清單的entry方法調用。

ProcessorSlotChain#entry方法的調用過程如圖3.1所示。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

圖3.1 ProcessorSlotChain#entry方法的調用過程

3. Tracer#trace方法

當調用SphU#entry方法或執行資源方法抛出異常時,如果抛出的是非BlockException異常,則調用Tracer#trace方法統計異常名額。

Tracer#trace方法最終會調用Tracer#traceExceptionToNode方法。

Tracer#traceExceptionToNode方法的源碼如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

Sentinel隻為一個資源建立一個ClusterNode,用于統計一個資源的全局名額資料,熔斷降級與限流降級都使用了這個ClusterNode。

ClusterNode類的trace方法的實作代碼如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

4. Entry#exit方法

在調用SphU#entry方法時,SphU#entry方法會傳回一個CtEntry執行個體,那麼在調用資源方法後,無論是出現異常還是正常執行完成,都需要調用一次該CtEntry執行個體的exit方法。

下面是CtEntry執行個體的exit方法的實作,為了簡短且易于了解,給出的是删減後的exitForContext方法的源碼。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

CtSph在建立CtEntry執行個體時,将資源的ProcessorSlotChain指派給了CtEntry執行個體,是以在調用CtEntry執行個體的exit方法時,CtEntry執行個體能夠拿到目前資源的ProcessorSlotChain,并調用ProcessorSlotChain的exit方法完成一次單向連結清單的exit方法調用。其調用過程與ProcessorSlotChain#entry方法的調用過程一樣。

在第2章介紹CtEntry時提到過,CtEntry用于維護父子Entry,每調用一次SphU#entry方法都會建立一個CtEntry執行個體。如果在應用處理一次請求的路徑上多次調用SphU#entry方法,那麼這些CtEntry執行個體會構成一個雙向連結清單。在每次建立CtEntry執行個體時,都會将Context執行個體的curEntry字段指向這個新的CtEntry執行個體,雙向連結清單的作用就是在調用CtEntry執行個體的exit方法時,能夠将Context執行個體的curEntry字段指向上一個CtEntry執行個體。

5. ContextUtil#exit方法

ContextUtil#enter方法在調用鍊入口建立Context執行個體,且建立的Context執行個體會被存儲到ContextUtil類的一個類型為ThreadLocal的靜态變量中,是以在退出方法之前必須調用一次ContextUtil#exit方法,進而将Context執行個體從ThreadLocal中移除。

ContextUtil#exit方法的源碼如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

• 如果Context執行個體的curEntry字段值為空,則說明所有SphU#entry方法建立的Entry執行個體都執行了一次exit方法,此時就可以将Context執行個體從ThreadLocal中移除。

ContextUtil#enter方法與ContextUtil#exit方法并不是必須調用的,當不需要為資源區分不同調用鍊入口的配置限流規則時可以被省略,但Context執行個體是調用鍊上方法執行所依賴的環境,是以,在預設的情況下,Sentinel會自動建立一個調用鍊入口名稱為sentinel_default_context的Context執行個體,同時會建立一個調用鍊入口名稱為sentinel_default_context的入口節點。

省略調用ContextUtil#enter方法與ContextUtil#exit方法的demo如下。

一線網際網路大牛深度解析微服務高并發Sentinel的整體工作流程分析

在處理一次請求的過程中,Sentinel會為調用鍊上的每個資源都建立一個CtEntry執行個體,每個CtEntry執行個體引用資源對應的ProcessorSlotChain。CtEntry維護雙向連結清單的目的:在下一個資源方法執行結束時,能夠将Context執行個體引用的CtEntry執行個體回退為引用上一個資源方法的CtEntry執行個體,以便随時通過Context執行個體擷取目前資源的ProcessorSlotChain。

Sentinel的整體工作流程可總結如下。

(1)調用ContextUtil#enter方法建立Context執行個體,建立的Context執行個體會被存儲到ThreadLocal中,在調用鍊上可以随時擷取該Context執行個體。

(2)調用SphU#entry方法建立CtEntry執行個體,調用ProcessorSlotChain#entry方法。如果是首次通路資源,則需要為資源建立ProcessorSlotChain。注冊在ProcessorSlotChain上的每個ProcessorSlot都是一個流量切入點。

(3)若在調用SphU#entry方法時抛出BlockException,則說明目前請求被拒絕;若在調用業務方法時抛出異常,則會收集異常名額資料。

(4)在調用SphU#entry方法後,需要確定調用一次SphU#entry方法傳回的Entry執行個體的exit方法,并由Entry執行個體調用ProcessorSlotChain的exit方法。

(5)在調用ContextUtil#entry方法後,需要確定調用一次ContextUtil#exit方法,将Context執行個體從ThreadLocal中移除。

本文給大家講解的内容是深度解析微服務高并發了解整體工作流程:Sentinel的整體工作流程分析

  1. 下篇文章給大家講解的内容是深度解析微服務高并發資源名額資料統計:基于滑動視窗實作資源名額資料統計
  2. 感謝大家的支援!

繼續閱讀