1. 程式人生 > >尋找一把進入 Alibaba Sentinel 的鑰匙(文末附流程圖)

尋找一把進入 Alibaba Sentinel 的鑰匙(文末附流程圖)

經過前面幾篇文章的鋪墊,我們正式來探討 Sentinel 的 entry 方法的實現流程。即探究進入 Alibaba Sentinel 核心的一把鑰匙。 @[TOC](本節目錄) 無論是從 Sentinel 適配 Dubbo 也好,還是 SphU 原始碼中的註釋中能看出,對一個資源進行限流或熔斷,通常需要呼叫 SphU 的 entry 方法,例如如下示例程式碼。 ~~~java public void foo() { Entry entry = null; try { entry = SphU.entry("abc"); } catch (BlockException blockException) { // when goes there, it is blocked // add blocked handle logic here } catch (Throwable bizException) { // business exception Tracer.trace(bizException); } finally { // ensure finally be executed if (entry != null){ entry.exit(); } } } ~~~ 那本文將來探討 SphU.entry 的實現原理。SphU 類定義了很多 entry 過載方法,我們就以下面這個方法為例來探究其實現原理。 ## 1、SphU.entry 流程分析 ~~~java public static Entry entry(String name, EntryType type, int count, Object... args) throws BlockException { // @1 return Env.sph.entry(name, type, count, args); // @2 } ~~~ 程式碼@1:我們先來簡單介紹其核心引數的含義: - String name 資源的名稱。 - EntryType type 進入資源的方式,主要包含 EntryType.IN、EntryType.OUT。 - int count 可以理解為本次進入需要消耗的“令牌數”。 - Object... args 其他引數。 程式碼@2:呼叫 Env.sph.entry 的方法,其最終會呼叫 CtSph 的 entry 方法。 接下來我們將重點檢視 CtSph 的 entry 方法。 ~~~java public Entry entry(String name, EntryType type, int count, Object... args) throws BlockException { StringResourceWrapper resource = new StringResourceWrapper(name, type); // @1 return entry(resource, count, args); // @2 } ~~~ 程式碼@1:由於該方法用來表示資源的方式為一個字串,故建立一個 StringResourceWrapper 物件來表示一個 Sentinel 中的資源,另外一個實現為 MethodResourceWrapper,用來表示方法類的資源。 程式碼@2:繼續呼叫 CtSph 的另外一個 entry 過載方法,最終會呼叫 entryWithPriority 方法。 CtSph#entryWithPriority ~~~java private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args) // @1 throws BlockException { Context context = ContextUtil.getContext(); // @2 if (context instanceof NullContext) { return new CtEntry(resourceWrapper, null, context); } if (context == null) { // Using default context. context = InternalContextUtil.internalEnter(Constants.CONTEXT_DEFAULT_NAME); } if (!Constants.ON) { // @3 return new CtEntry(resourceWrapper, null, context); } Proce