Eureka Server之注冊(cè)實(shí)例自我保護(hù)機(jī)制

自我保護(hù)機(jī)制定義

當(dāng)Eureka Server節(jié)點(diǎn)在短時(shí)間內(nèi)丟失過多客戶端時(shí)(可能發(fā)生了網(wǎng)絡(luò)分區(qū)故障)赶撰,那么這個(gè)節(jié)點(diǎn)就會(huì)進(jìn)入自我保護(hù)模式贮尉。一旦進(jìn)入該模式琼了,Eureka Server就會(huì)保護(hù)服務(wù)注冊(cè)表中的信息嫡丙,不再刪除服務(wù)注冊(cè)表中的數(shù)據(jù)(也就是不會(huì)注銷任何微服務(wù))。當(dāng)網(wǎng)絡(luò)故障恢復(fù)后快鱼,該Eureka Server節(jié)點(diǎn)會(huì)自動(dòng)退出自我保護(hù)模式颠印。

自我保護(hù)機(jī)制意義

自我保護(hù)模式是一種應(yīng)對(duì)網(wǎng)絡(luò)異常的安全保護(hù)措施。它的架構(gòu)哲學(xué)是寧可同時(shí)保留所有微服務(wù)(健康的微服務(wù)和不健康的微服務(wù)都會(huì)保留)抹竹,也不盲目注銷任何健康的微服務(wù)线罕。使用自我保護(hù)模式,可以讓Eureka集群更加的健壯柒莉、穩(wěn)定

自我保護(hù)機(jī)制實(shí)現(xiàn)
  1. 相關(guān)的參數(shù)列表
    /**
     * 注冊(cè)服務(wù)每分鐘發(fā)送的心跳數(shù)統(tǒng)計(jì)信息
     */
    private final MeasuredRate renewsLastMin;
    /**
     * 期望每分鐘更新(續(xù)租闻坚,發(fā)送心跳)的最小次數(shù)
     */
    protected volatile int numberOfRenewsPerMinThreshold;
    /**
     * 期望每分鐘更新(續(xù)租沽翔,發(fā)送心跳)的最大次數(shù)
     */
    protected volatile int expectedNumberOfRenewsPerMin;
    
  1. 相關(guān)的配置信息
- eureka.server.renewal-percent-threshold =0.85 默認(rèn)值等于0.85
- eureka.server.enable-self-preservation =true(默認(rèn)true兢孝,表示開啟)
  • [x] 配置獲取方式

    /**
     *  觸發(fā)自我保護(hù)機(jī)制的閥值配置信息
     *  eureka.server.renewal-percent-threshold =0.85 默認(rèn)值等于0.85
     *  用于計(jì)算期望更新最小次數(shù)
     * @return
     */
    @Override
    public double getRenewalPercentThreshold() {
        return configInstance
                .getDoubleProperty(namespace + "renewalPercentThreshold", 0.85)
                .get();
    }
    
    /**
     * 自我保護(hù)開關(guān)配置信息
     * eureka.server.enable-self-preservation =true(默認(rèn)true,表示開啟)
     * 用于判斷是否開啟自我保護(hù)模式
     * @return
     */
    @Override
    public boolean shouldEnableSelfPreservation() {
        return configInstance
                .getBooleanProperty(namespace + "enableSelfPreservation", true)
                .get();
    }

  1. 觸發(fā)條件
  1. eureka.server.enable-self-preservation =true
  2. numberOfRenewsPerMinThreshold > 0
  3. renewsLastMin > numberOfRenewsPerMinThreshold

條件之間且關(guān)系: 1 && 2 && 3 ;即當(dāng)每分鐘期望最小的更新次數(shù)大于0時(shí)仅偎,以及每分鐘心跳次數(shù)( renewsLastMin ) 小于 numberOfRenewsPerMinThreshold 時(shí)跨蟹,并且開啟自動(dòng)保護(hù)模式開關(guān)( eureka.enableSelfPreservation = true ) 時(shí),觸發(fā)自動(dòng)保護(hù)機(jī)制橘沥,不再自動(dòng)過期租約

觸發(fā)條件的具體實(shí)現(xiàn)在PeerAwareInstanceRegistryImpl類下窗轩,具體如下:

 /**
     * 判斷是否進(jìn)入自我保護(hù)模式,當(dāng)返回false觸發(fā)自我保護(hù)模式座咆,不在下線服務(wù)
     * @return
     */
    @Override
    public boolean isLeaseExpirationEnabled() {
        //開關(guān)判斷
        if (!isSelfPreservationModeEnabled()) {
            // The self preservation mode is disabled, hence allowing the instances to expire.
            return true;
        }
        //每分鐘心跳次數(shù)判斷
        // 每分鐘期望最小的更新次數(shù)大于0時(shí)痢艺,以及每分鐘心跳次數(shù)( renewsLastMin ) 小于 numberOfRenewsPerMinThreshold 時(shí),返回true
        return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
    }

自我保護(hù)機(jī)制參數(shù)的計(jì)算以及取值
  1. renewsLastMin (每分鐘心跳發(fā)送的次數(shù))

renewsLastMin 用來統(tǒng)計(jì)每分鐘所有實(shí)例發(fā)送心跳的次數(shù)仓洼,數(shù)據(jù)每分鐘更新一次,當(dāng)前獲取的是上一分鐘的統(tǒng)計(jì)數(shù)據(jù)堤舒,默認(rèn)情況下色建,每個(gè)實(shí)例30s發(fā)送一次心跳,每個(gè)實(shí)例每分鐘發(fā)送2次心跳舌缤。正常情況每分鐘統(tǒng)計(jì)數(shù)據(jù)為:實(shí)例數(shù)*2

renewsLastMin 在實(shí)例發(fā)送心跳時(shí)自增1箕戳,具體在AbstractInstanceRegistry.renew方法,實(shí)現(xiàn)如下:

    //心跳統(tǒng)計(jì)數(shù)據(jù)+1
    renewsLastMin.increment();
            //租約刷新
    leaseToRenew.renew();

==備注:== MeasuredRate 是一個(gè)速率測(cè)量工具類国撵,具體實(shí)現(xiàn)可以自行查看

  1. expectedNumberOfRenewsPerMin (期望每分鐘最大更新次數(shù))與numberOfRenewsPerMinThreshold(期望每分鐘最小的更新次數(shù))

由于expectedNumberOfRenewsPerMin與numberOfRenewsPerMinThreshold總是同時(shí)計(jì)算以及同時(shí)更新陵吸,在此合并在一起分析。

計(jì)算方式如下:

  • expectedNumberOfRenewsPerMin = 當(dāng)前注冊(cè)的應(yīng)用實(shí)例數(shù)*2
  • numberOfRenewsPerMinThreshold=expectedNumberOfRenewsPerMin*續(xù)租百分比(eureka.server.renewal-percent-threshold =0.85 )

  • 期望每分鐘最大更新次數(shù)為實(shí)例數(shù) * 2,為什么呢?在renewsLastMin部分我們分析過介牙,在正常情況下壮虫,每個(gè)實(shí)例每分鐘的心跳數(shù)為2,(30s一次)耻瑟,每分鐘的最大值就是實(shí)例數(shù) * 2,這里我們期望的最大值就是在所有服務(wù)都正常的情況下旨指,每分鐘的心跳數(shù)
  • 期望每分鐘最小更新數(shù)為期望最大值*續(xù)租的續(xù)租百分比,當(dāng)每分種的心跳數(shù)小于期望最小值是就開啟自我保護(hù)喳整,不在下線服務(wù) ( renewsLastMin > numberOfRenewsPerMinThreshold)

expectedNumberOfRenewsPerMin 與numberOfRenewsPerMinThreshold參數(shù)計(jì)算更新時(shí)機(jī)

  • 服務(wù)初始化時(shí)(PeerAwareInstanceRegistryImpl.openForTraffic)
    public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
        // Renewals happen every 30 seconds and for a minute it should be a factor of 2.
        this.expectedNumberOfRenewsPerMin = count * 2;
        this.numberOfRenewsPerMinThreshold =
                (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
        logger.info("Got " + count + " instances from neighboring DS node");
        logger.info("Renew threshold is: " + numberOfRenewsPerMinThreshold);
        this.startupTime = System.currentTimeMillis();
        if (count > 0) {
            this.peerInstancesTransferEmptyOnStartup = false;
        }
        DataCenterInfo.Name selfName = applicationInfoManager.getInfo().getDataCenterInfo().getName();
        boolean isAws = Name.Amazon == selfName;
        if (isAws && serverConfig.shouldPrimeAwsReplicaConnections()) {
            logger.info("Priming AWS connections for all replicas..");
            primeAwsReplicas(applicationInfoManager);
        }
        logger.info("Changing status to UP");
        applicationInfoManager.setInstanceStatus(InstanceStatus.UP);
        super.postInit();
    }
  • 實(shí)例注冊(cè)時(shí)(AbstractInstanceRegistry.register)
                //服務(wù)實(shí)例信息不存在與集群中
                // The lease does not exist and hence it is a new registration
                synchronized (lock) {
                    if (this.expectedNumberOfRenewsPerMin > 0) {
                        // Since the client wants to cancel it, reduce the threshold
                        // (1
                        // for 30 seconds, 2 for a minute)
                        this.expectedNumberOfRenewsPerMin = this.expectedNumberOfRenewsPerMin + 2;
                        this.numberOfRenewsPerMinThreshold =
                                (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
                    }
                }
  • 定時(shí)重置(PeerAwareInstanceRegistryImpl.updateRenewalThreshold)
  private void scheduleRenewalThresholdUpdateTask() {
        timer.schedule(new TimerTask() {
                           @Override
                           public void run() {
                               updateRenewalThreshold();
                           }
                       }, serverConfig.getRenewalThresholdUpdateIntervalMs(),
                serverConfig.getRenewalThresholdUpdateIntervalMs());
    }
  • 服務(wù)下線(PeerAwareInstanceRegistryImpl.cancel)
    public boolean cancel(final String appName, final String id,
                          final boolean isReplication) {
        if (super.cancel(appName, id, isReplication)) {
            replicateToPeers(Action.Cancel, appName, id, null, null, isReplication);
            synchronized (lock) {
                if (this.expectedNumberOfRenewsPerMin > 0) {
                    // Since the client wants to cancel it, reduce the threshold (1 for 30 seconds, 2 for a minute)
                    this.expectedNumberOfRenewsPerMin = this.expectedNumberOfRenewsPerMin - 2;
                    this.numberOfRenewsPerMinThreshold =
                            (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
                }
            }
            return true;
        }
        return false;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谆构,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子框都,更是在濱河造成了極大的恐慌搬素,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魏保,死亡現(xiàn)場(chǎng)離奇詭異熬尺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谓罗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門粱哼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人檩咱,你說我怎么就攤上這事揭措。” “怎么了刻蚯?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵绊含,是天一觀的道長。 經(jīng)常有香客問我炊汹,道長躬充,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮充甚,結(jié)果婚禮上以政,老公的妹妹穿的比我還像新娘。我一直安慰自己伴找,他們只是感情好妙蔗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疆瑰,像睡著了一般眉反。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上穆役,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天寸五,我揣著相機(jī)與錄音,去河邊找鬼耿币。 笑死梳杏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淹接。 我是一名探鬼主播十性,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼塑悼!你這毒婦竟也來了劲适?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤厢蒜,失蹤者是張志新(化名)和其女友劉穎霞势,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斑鸦,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡愕贡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了巷屿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片固以。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嘱巾,靈堂內(nèi)的尸體忽然破棺而出憨琳,到底是詐尸還是另有隱情,我是刑警寧澤浓冒,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布栽渴,位于F島的核電站尖坤,受9級(jí)特大地震影響稳懒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一场梆、第九天 我趴在偏房一處隱蔽的房頂上張望墅冷。 院中可真熱鬧,春花似錦或油、人聲如沸寞忿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腔彰。三九已至,卻和暖如春辖佣,著一層夾襖步出監(jiān)牢的瞬間霹抛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國打工卷谈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杯拐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓世蔗,卻偏偏與公主長得像端逼,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子污淋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理顶滩,服務(wù)發(fā)現(xiàn),斷路器寸爆,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 概述 著名的CAP理論指出诲祸,一個(gè)分布式系統(tǒng)不可能同時(shí)滿足C(一致性)、A(可用性)和P(分區(qū)容錯(cuò)性)而昨。由于分區(qū)容錯(cuò)...
    PKAQ閱讀 3,842評(píng)論 0 13
  • 1 為什么需要服務(wù)發(fā)現(xiàn) 簡(jiǎn)單來說救氯,服務(wù)化的核心就是將傳統(tǒng)的一站式應(yīng)用根據(jù)業(yè)務(wù)拆分成一個(gè)一個(gè)的服務(wù),而微服務(wù)在這個(gè)基...
    謙小易閱讀 25,080評(píng)論 4 93
  • Demo 源碼下載 本案例為源碼分支的 eureka 分支 服務(wù)發(fā)現(xiàn)概述 服務(wù)發(fā)現(xiàn)機(jī)制是為了解決硬網(wǎng)絡(luò)編碼問題歌憨,服...
    聰明的奇瑞閱讀 5,180評(píng)論 0 13
  • 《后來的我們》從首映到今天着憨,一直爭(zhēng)議不斷,豆瓣評(píng)分從6.9降到了5.9务嫡,周圍的人對(duì)劉若英首次執(zhí)導(dǎo)的這部電影評(píng)價(jià)也都...
    無飯不起早閱讀 508評(píng)論 0 2