sentinal源碼2-初始化

  • 包含很多static的初始化塊魄衅,并通過(guò)ServiceLoader的方式加載各種類

一 static初始化塊

static初始化塊.png

二 CtSph

  • 提供資源請(qǐng)求entry初始化函數(shù)

2.1 同步context

  • 1 超過(guò)可限流的context入口類型數(shù)晃虫,則不做限流
  • 2 未指定則使用默認(rèn)名稱的context入口節(jié)點(diǎn)
  • 3 全局限流開(kāi)關(guān)Constants.ON,關(guān)閉則不做限流
  • 4 獲取當(dāng)前資源對(duì)應(yīng)的處理鏈毅访,每個(gè)資源對(duì)應(yīng)一個(gè)處理鏈盘榨,名稱活方法表示資源
  • 5 資源對(duì)應(yīng)的資源節(jié)點(diǎn)處理鏈數(shù)達(dá)到上限,則后續(xù)資源請(qǐng)求不做處理
  • 6 實(shí)例化資源請(qǐng)求Entry守呜,按資源節(jié)點(diǎn)處理鏈依次處理山憨,進(jìn)行統(tǒng)計(jì)郁竟,資源申請(qǐng)等操作
  • 7 資源申請(qǐng)失敗,按處理鏈做失敗統(tǒng)計(jì)等處理
private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)
    throws BlockException {
    Context context = ContextUtil.getContext();
    if (context instanceof NullContext) { //1
        return new CtEntry(resourceWrapper, null, context);
    }

    if (context == null) {//2
        context = MyContextUtil.myEnter(Constants.CONTEXT_DEFAULT_NAME, "", resourceWrapper.getType());
    }

    if (!Constants.ON) {//3
        return new CtEntry(resourceWrapper, null, context);
    }

    ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);//4

    if (chain == null) {//5
        return new CtEntry(resourceWrapper, null, context);
    }
  
    Entry e = new CtEntry(resourceWrapper, chain, context);
    try {
        chain.entry(context, resourceWrapper, null, count, prioritized, args);//6
    } catch (BlockException e1) {
        e.exit(count, args);//7
        throw e1;
    } catch (Throwable e1) {
        RecordLog.info("Sentinel unexpected exception", e1);
    }
    return e;
}

2.1.1 lookProcessChain

  • 根據(jù)context名稱獲取處理鏈
  • 使用hashmap存儲(chǔ)
    private static volatile Map<ResourceWrapper, ProcessorSlotChain> chainMap = new HashMap<ResourceWrapper, ProcessorSlotChain>();
  • 二次加鎖校驗(yàn)方式初始化
  • 寫拷貝更新的方式更新存儲(chǔ)map
ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) {
    ProcessorSlotChain chain = chainMap.get(resourceWrapper);
    if (chain == null) {
        synchronized (LOCK) {
            chain = chainMap.get(resourceWrapper);
            if (chain == null) {
                // Entry size limit.
                if (chainMap.size() >= Constants.MAX_SLOT_CHAIN_SIZE) {
                    return null;
                }

                chain = SlotChainProvider.newSlotChain();
                Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>(
                    chainMap.size() + 1);
                newMap.putAll(chainMap);
                newMap.put(resourceWrapper, chain);
                chainMap = newMap;
            }
        }
    }
    return chain;
}

2.1.2 獲取資源節(jié)點(diǎn)處理鏈

public ProcessorSlotChain build() {
    ProcessorSlotChain chain = new DefaultProcessorSlotChain();
    chain.addLast(new NodeSelectorSlot());
    chain.addLast(new ClusterBuilderSlot());
    chain.addLast(new LogSlot());
    chain.addLast(new StatisticSlot());
    chain.addLast(new SystemSlot());
    chain.addLast(new AuthoritySlot());
    chain.addLast(new FlowSlot());
    chain.addLast(new DegradeSlot());

    return chain;
}

2.2 異步context

//todo

三 Entry

3.1 類結(jié)構(gòu)圖

entry類.png

3.2 CtEntry

3.2.1 實(shí)例化

  • Entry實(shí)例化
  • 保存資源處理鏈讥蟆,資源處理上下文context
CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
    super(resourceWrapper);
    this.chain = chain;
    this.context = context;

    setUpEntryFor(context);
}
  • 設(shè)置Entry父子關(guān)系,更新context.curEntry為本次新建的Entry
private void setUpEntryFor(Context context) {
    // The entry should not be associated to NullContext.
    if (context instanceof NullContext) {
        return;
    }
    this.parent = context.getCurEntry();
    if (parent != null) {
        ((CtEntry)parent).child = this;
    }
    context.setCurEntry(this);
}
  • 保存對(duì)應(yīng)的context名稱
  • 保存資源請(qǐng)求時(shí)間
public Entry(ResourceWrapper resourceWrapper) {
    this.resourceWrapper = resourceWrapper;
    this.createTime = TimeUtil.currentTimeMillis();
}

3.2.2 資源請(qǐng)求失敗處理

  • 1 失敗的entry非context當(dāng)前entry修然,則按entry父子關(guān)系依次向上調(diào)用所有entry的失敗處理函數(shù)exit()
  • 2 失敗entry是context的當(dāng)前entry质况,
    調(diào)用資源處理鏈的exit函數(shù)
    更新context的curEntry為請(qǐng)求失敗Entry的父節(jié)點(diǎn)Entry
    刪除Entry的父子關(guān)系
    如Entry無(wú)父節(jié)點(diǎn),則若是默認(rèn)context則需要自動(dòng)清理中贝,手動(dòng)配置的context則由用戶手動(dòng)退出潭陪。
    清理Entry的context屬性
protected void exitForContext(Context context, int count, Object... args) throws ErrorEntryFreeException {
    if (context != null) {
        // Null context should exit without clean-up.
        if (context instanceof NullContext) {
            return;
        }
        if (context.getCurEntry() != this) {//1
            String curEntryNameInContext = context.getCurEntry() == null ? null : context.getCurEntry().getResourceWrapper().getName();
            // Clean previous call stack.
            CtEntry e = (CtEntry)context.getCurEntry();
            while (e != null) {
                e.exit(count, args);
                e = (CtEntry)e.parent;
            }
            String errorMessage = String.format("The order of entry exit can't be paired with the order of entry"
                + ", current entry in context: <%s>, but expected: <%s>", curEntryNameInContext, resourceWrapper.getName());
            throw new ErrorEntryFreeException(errorMessage);
        } else {//2
            if (chain != null) {
                chain.exit(context, resourceWrapper, count, args);
            }
            context.setCurEntry(parent);
            if (parent != null) {
                ((CtEntry)parent).child = null;
            }
            if (parent == null) {
                if (ContextUtil.isDefaultContext(context)) {
                    ContextUtil.exit();
                }
            }
            clearEntryContext();
        }
    }
}
  • 清理線程變量緩存的context
public static void exit() {
    Context context = contextHolder.get();
    if (context != null && context.getCurEntry() == null) {
        contextHolder.set(null);
    }
}

3.3 AsyncEntry

//todo

四 節(jié)點(diǎn)關(guān)系圖

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市黎炉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淀弹,老刑警劉巖庆械,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異缭乘,居然都是意外死亡沐序,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門堕绩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)策幼,“玉大人,你說(shuō)我怎么就攤上這事奴紧√亟悖” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵黍氮,是天一觀的道長(zhǎng)唐含。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沫浆,這世上最難降的妖魔是什么觉壶? 我笑而不...
    開(kāi)封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任件缸,我火速辦了婚禮铜靶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘他炊。我一直安慰自己争剿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布痊末。 她就那樣靜靜地躺著蚕苇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凿叠。 梳的紋絲不亂的頭發(fā)上涩笤,一...
    開(kāi)封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天嚼吞,我揣著相機(jī)與錄音,去河邊找鬼蹬碧。 笑死舱禽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恩沽。 我是一名探鬼主播誊稚,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼罗心!你這毒婦竟也來(lái)了里伯?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤渤闷,失蹤者是張志新(化名)和其女友劉穎疾瓮,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體飒箭,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爷贫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了补憾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漫萄。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盈匾,靈堂內(nèi)的尸體忽然破棺而出腾务,到底是詐尸還是另有隱情,我是刑警寧澤削饵,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布岩瘦,位于F島的核電站,受9級(jí)特大地震影響窿撬,放射性物質(zhì)發(fā)生泄漏启昧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一劈伴、第九天 我趴在偏房一處隱蔽的房頂上張望密末。 院中可真熱鬧,春花似錦跛璧、人聲如沸严里。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)刹碾。三九已至,卻和暖如春座柱,著一層夾襖步出監(jiān)牢的瞬間迷帜,已是汗流浹背物舒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戏锹,地道東北人冠胯。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像景用,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惭蹂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354