欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:云原生 Eureka處理流程

柚子快報邀請碼778899分享:云原生 Eureka處理流程

http://yzkb.51969.com/

1、Eureka Server服務(wù)端會做什么

1、服務(wù)注冊 Client服務(wù)提供者可以向Server注冊服務(wù),并且內(nèi)部有二層緩存機制來維護整個注冊表,注冊表是Eureka Client的服務(wù)提供者注冊進來的。 2、提供注冊表 服務(wù)消費者用來獲取注冊表 3、同步狀態(tài) 通過注冊、心跳機制和 Eureka Server同步當(dāng)前客戶端的狀態(tài),這里就包括服務(wù)提供者和服務(wù)消費者。

2、Eureka Server的問題

問題: 1、Eureka Server的自我保護機制是怎么實現(xiàn),怎么做到15分鐘內(nèi),服務(wù)心跳失敗比例高于85%。

2、自我保護機制觸發(fā)后,有哪些功能會被開啟

1、不再從注冊列表中移除因為長時間沒收到心跳而應(yīng)該過期的服務(wù),冷卻時間是多久? 2、仍然能夠接受新服務(wù)的注冊和查詢注冊表請求,但是不會被同步到其它節(jié)點上 3、當(dāng)網(wǎng)絡(luò)穩(wěn)定時,當(dāng)前實例新的注冊信息會被同步到其它節(jié)點中,怎么判斷網(wǎng)絡(luò)恢復(fù)

集群問題:

Eureka Server集群中,Eureka Server節(jié)點A和Eureka Server節(jié)點B是怎么通過P2P的方式完成服務(wù)注冊表的同步?

Eureka Server集群中,同一個區(qū)域的Eureka Client,怎么做到優(yōu)先和同區(qū)域內(nèi)的Eureka Server進行通信的?

Eureka Client服務(wù)提供者,向Eureka Server注冊,如果某個節(jié)點失敗,自動切換到其他節(jié)點,是怎么做到的?

Eureka Server什么時候會自動退出自我保護模式?

二、源碼概述

1、EurekaServer啟動

@EnableEurekaServer->

import(EurekaServerMarkerConfiguration)->

注冊Bean(EurekaServerMarkerConfiguration.Marker)->

Marker激活了EurekaServerAutoConfiguration這個配置類

2、EurekaServerAutoConfiguration主要包含以下內(nèi)容

1、創(chuàng)建Bean:【EurekaServerConfigBean】是一個配置類,EurekaServer的所有配置項都是EurekaServerConfigBean這個類里面。 2、創(chuàng)建Bean:【EurekaController】也就是我們通過url,可以訪問EurekaServer后臺。 3、創(chuàng)建Bean:【PeerAwareInstanceRegistry】處理注冊表的類,這個類也會發(fā)布事件,發(fā)布了注冊事件和取消事件(默認(rèn)沒有監(jiān)聽者需要自己實現(xiàn)) 4、創(chuàng)建Bean:【PeerEurekaNodes】初始化了集群節(jié)點集合 5、創(chuàng)建Bean:【EurekaServerContext】專業(yè)名稱叫【EurekaServer上下文】,這個Bean的生成是基于上面創(chuàng)建的Bean: eureka server配置,注冊表,集群節(jié)點集合來生成。而EurekaServerContext的作用就是初始化eurekaServer上下文,里面會做很多事情。 6、創(chuàng)建Bean:【EurekaServerBootstrap】Eureka Server的啟動類 7、創(chuàng)建Bean:【FilterRegistrationBean】主要是對Jersey過濾器的包裝,那么這個過濾器干嘛用的 ?

到此EurekaServerAutoConfiguration的創(chuàng)建Bean的任務(wù)完成了,但是EurekaServerAutoConfiguration里面還有一@Import(EurekaServerInitializerConfiguration)注解

3、EurekaServerInitializerConfiguration

EurekaServerInitializerConfiguration里面有個start方法,里面會拿到上面注冊Bean:【EurekaServerBootstrap啟動類】,來啟動Eureak。 然后在通過生成的【EurekaServer上下文】開始初始化,初始化的時候會調(diào)用registry.syncUp方法,從相鄰的eureka節(jié)點復(fù)制注冊表,通過http調(diào)用相鄰節(jié)點獲取所有服務(wù)實例。

在通過上面的【PeerAwareInstanceRegistry】把實例注冊到本地,這里的實例是指EurekaClient的服務(wù)提供者,同時PeerAwareInstanceRegistry里面還有一個【Timer】,這個是定時任務(wù),清理30s沒有續(xù)約的任務(wù)、服務(wù)剔除超過90s沒過來續(xù)約的服務(wù)。

原文地址:跳轉(zhuǎn)

三、下面通過代碼原理說下實現(xiàn)邏輯

1、服務(wù)注冊 2、服務(wù)續(xù)約 3、服務(wù)剔除 4、服務(wù)下線 5、服務(wù)發(fā)現(xiàn) 6、集群信息同步

1、服務(wù)注冊

流程:服務(wù)提供者,請求EurekaServer端某個節(jié)點注冊服務(wù)

EurekaClient端

Bean =【EurekaAutoServiceRegistration】

通過com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient#register向EurekaServer注冊服務(wù)。

EurekaServer端

EurekaServer收到請求,請求進到ApplicationResource#addInstance方法,里面調(diào)用【Bean=PeerAwareInstanceRegistry】#register方法,

里面先發(fā)布一個Event事件,但是Spring沒有監(jiān)聽這個事件,這個是留給我們自己拓展用的,在register里面還有一個很重要的事做,就是注冊:

1、首先是設(shè)置服務(wù)的過期時間90s

2、調(diào)用父類完成服務(wù)注冊,

3、在完成集群信息同步,同步給其他節(jié)點。

重點看調(diào)用【父類完成注冊】,先從注冊表的集合中獲取服務(wù)注冊信息:

1、如果注冊表存在,那么說明沖突了,就判斷哪2個節(jié)點的活躍時間比較靠前,保留節(jié)點時間最新的節(jié)點

2、如果不存在就新建,將EurekaClient的服務(wù)提供者封裝成InstanceInfo對象, InstanceInfo存放了注冊信息,最后操作時間,注冊時間,過期時間,

剔除時間等信息,再把這個InstanceInfo對象存到注冊表中去。至此一個服務(wù)注冊的流程就完成了

注意:注冊表是一個Map>>對象

1、最外層的key是AppName,注冊進來的服務(wù)的服務(wù)名 , value = Map> value表示這個服務(wù)名對應(yīng)多個實例節(jié)點

2、Map>這個Map,key是ip+端口,value是Lease對象,也就是這個實例的更多信息,比如過期時間,最近活躍時間等等。

2、服務(wù)續(xù)約:

服務(wù)續(xù)約由Eureka-client端主動發(fā)起請求Eureka服務(wù)端,間隔時間30s,Eureka服務(wù)端收到請求,刷新節(jié)點的活躍時間。因為Eureka服務(wù)端,有定時任務(wù),就是基于這個活躍時間來考慮是否剔除服務(wù)。

Eureka-client端

請求Eureka服務(wù)端,由DiscoveryClient#renew方法完成,主要是發(fā)送http請求,每隔30秒進行一次續(xù)約,

里面調(diào)用AbstractJerseyEurekaHttpClient#sendHeartBeat方法

Eureka-server端

在Eureka-server端服務(wù)續(xù)約的調(diào)用鏈與服務(wù)注冊基本相同

InstanceRegistry#renew() ->

PeerAwareInstanceRegistry#renew()->

AbstractInstanceRegistry # renew() 主要邏輯還是AbstractInstanceRegistry的renew方法

renew的方法邏輯操作非常簡單,它的本質(zhì)就是修改服務(wù)的【最后更新時間】。將最后更新時間改為:【系統(tǒng)當(dāng)前時間】+【服務(wù)的過期時間】

3、服務(wù)剔除

服務(wù)主要是Eureka服務(wù)端,通過定時任務(wù)檢測注冊節(jié)點的【活躍時間】,如果超過90s就會剔除。

Eureka-server端

當(dāng)Eureka-server發(fā)現(xiàn)有的實例沒有續(xù)約超過一定時間,則將該服務(wù)從注冊列表剔除,該項工作由一個定時任務(wù)完成的。由下面方法完成

AbstractInstanceRegistry # postInit()

定時任務(wù)前面說了在【EurekaServer上下文】初始化的時候,添加了一個Timer定時器,定時器關(guān)聯(lián)的任務(wù)是EvictionTask的run方法,在執(zhí)行任務(wù)中

調(diào)用剔除方法 evict(), 主要是拿到注冊表的所有實例挨個遍歷,判斷【系統(tǒng)當(dāng)前時間 > 最后更新時間+過期時間+預(yù)留時間】,

并且新建實例列表expiredLeases,用來存放過期的實例。

當(dāng)該條件成立時,認(rèn)為服務(wù)過期(在Eureka中過期時間默認(rèn)定義為3個心跳的時間,一個心跳是30秒,因此過期時間是90秒)。

將該過期實例放入上面創(chuàng)建的expiredLeases列表中。注意這里僅僅是將實例放入List中,并沒有實際剔除。

因為要判斷是否超過閾值了,如果超過就從里面取隨機數(shù),隨機剔除實例ID,注意expiredLeases里面存的是多個服務(wù)的實

例,不是某一個服務(wù)的所有實例。下線的時候從里面取隨機數(shù),所以有可能某個服務(wù)的所有實例全部被剔除都有可能。

在實際剔除任務(wù)前,需要提一下eureka的自我保護機制:

當(dāng)1分鐘內(nèi),心跳失敗的服務(wù)大于一定比例時,會觸發(fā)自我保護機制。這個值在Eureka中被定義為85%,一旦觸發(fā)自我保護機制,

Eureka會嘗試保護其服務(wù)注冊表中的信息,不再刪除服務(wù)注冊表中的數(shù)據(jù)。1分鐘是怎么統(tǒng)計數(shù)量的?哪些節(jié)點保留? 哪些節(jié)點刪除?

答:使用了隨機算法進行剔除,

舉個例子,假如當(dāng)前共有100個服務(wù),那么剔除閾值為85%,也就是最多剔除15個,如果list中有60個服務(wù),

那么就會從60個服務(wù)里面取15個。有可能一個服務(wù)的所有節(jié)點全部被剔除。剔除的節(jié)點被放到一個queue里面,

這個里面存的是最近剔除的節(jié)點,在集群同步,或者拉取注冊表的時候,要用到。

關(guān)于自我保護

首先是閾值是85%,比如100個,閾值是85%,那么一次最多剔除15個,當(dāng)定時任務(wù)進來,發(fā)現(xiàn)100個里面有10個失效,那么10小于【最大閾值】,那就剔除10個,如果20個失效,20個大于15,所以最多剔除15個,這15個怎么選?

通過for循環(huán)15次,每次生成一個隨機數(shù),這個隨機數(shù)是從20里面取,

1、自我保護時期不能進行服務(wù)剔除操作

2、過期操作是分批進行

3、服務(wù)剔除是隨機逐個剔除,均勻分布在所有應(yīng)用中,其實也不算均勻,是隨機抽

4、服務(wù)剔除是一個定時任務(wù),默認(rèn)60秒一次

問題:自我保護時期不能進行服務(wù)剔除操作:這個是怎么做到的?

首先是定義了2個變量,一個是【期望續(xù)約數(shù)】,一個是【前一分鐘實際的續(xù)約數(shù)】。

這個【期望續(xù)約數(shù)】是通過公式算出來了,比如20個實例,正常情況下1分鐘的話會續(xù)約40次,

那么期望的續(xù)約數(shù)應(yīng)該是40*85%=34個,而如果實際契約數(shù)超過這個數(shù)量,比如35,

那么EurekaServer認(rèn)為,服務(wù)恢復(fù)正常了,應(yīng)該關(guān)閉自我保護機制。

注意:期望續(xù)約數(shù)是一個動態(tài)值,每次會重行計算的。比如服務(wù)下線或者上線,期望的數(shù)量是會加1或者減1的。

問題:實際續(xù)約數(shù)是怎么算出來的?

因為剔除的定時任務(wù)是1分鐘一次,所以有個定時任務(wù)專門設(shè)置【前一分鐘實際續(xù)約數(shù)量】,MeasuredRate也是60秒一次,他里面定義了2個變量,一個是【一分鐘內(nèi)的續(xù)約】數(shù),一個是【上一分鐘的續(xù)約數(shù)】,服務(wù)每次注冊就會加1,服務(wù)下線就減1,當(dāng)定時任務(wù)跑的時候,就會把一分鐘的續(xù)約數(shù)賦值給【上一分鐘的續(xù)約數(shù)】,然后再把【一分鐘內(nèi)的續(xù)約】置0

自我保護機制,詳細解讀:跳轉(zhuǎn) 代碼流程:跳轉(zhuǎn)

4、服務(wù)下線

當(dāng)eureka-client關(guān)閉時,不會立刻關(guān)閉,需要先發(fā)請求給eureka-server服務(wù)端,告知自己要下線了。

Eureka-client端:

Eureka客戶端請求EurekaServer服務(wù)端,通過DiscoveryClient#shutdown方法調(diào)用EurekaServer服務(wù)端

Eureka-server端

收到請求,進到AbstractInstanceRegistry#cancel方法, 最終還是調(diào)用了和服務(wù)剔除中一樣的方法,remove掉了注冊表中的實例

5、服務(wù)發(fā)現(xiàn)

是指EurekaClient 消費者,通過Http調(diào)用EurekaServer服務(wù)端接口,獲取注冊表信息

Eureka-client端:

DiscoveryClient#getInstances方法,可以根據(jù)服務(wù)id獲取服務(wù)實例列表。那么這里就有一個問題了,我們還沒有去調(diào)用微服務(wù),那么服務(wù)列表是什么時候被拉取或緩存到本地的服務(wù)列表的呢?

EurekaDiscoveryClient # getInstances() ->

DiscoveryClient # getInstancesByVipAddress() ->

DiscoveryClient #getInstancesByVipAddress2() ->

Applications # getInstancesByVirtualHostName() 這里居然不是走的http,是讀的本地緩存。

Applications中的getInstancesByVirtualHostName方法里面,有一個virtualHostNameAppMap的Map集合中已經(jīng)保存了當(dāng)前所有注冊到eureka的服務(wù)列表。

private final Map virtualHostNameAppMap;

也就是說,在我們沒有手動去調(diào)用服務(wù)的時候,該集合里面已經(jīng)有值了,說明在Eureka-server項目啟動后,會自動去拉取服務(wù),并將拉取的服務(wù)緩存起來。

那么追根溯源,來查找一下服務(wù)的發(fā)現(xiàn)究竟是什么時候完成的?;氐紻iscoveryClient這個類,

在它的構(gòu)造方法中定義了任務(wù)調(diào)度線程池cacheRefreshExecutor,定義完成后,調(diào)用initScheduledTask方法,

通過fetchRegistry方法來拉取,不過分2種情況【增量拉取】還是【全量拉取】

【全量拉取】:當(dāng)緩存為null,或里面的數(shù)據(jù)為空,或強制時,進行全量拉取,執(zhí)行g(shù)etAndStoreFullRegistry方法

【增量拉取】: 只拉取修改的。執(zhí)行g(shù)etAndUpdateDelta方法,雖然這里是拉增量,但是如果沒拉到數(shù)據(jù),

還是會拉全量的數(shù)據(jù),然后就是更新操作,更新也有類型,是delete還是Modify,added,這里有個細節(jié)校驗,

就是拿hashCode和緩存的HashCode對比是否一致,如果一致,說明數(shù)據(jù)沒有變動,如果不一致,

那就說明本地和遠程數(shù)據(jù)不一樣,需要重新再拉一次,

對服務(wù)發(fā)現(xiàn)過程進行一下重點總結(jié):

1、服務(wù)列表的拉取并不是在服務(wù)調(diào)用的時候才拉取,而是在項目啟動的時候就有定時任務(wù)去拉取了,這點在DiscoveryClient的構(gòu)造方法中能夠體現(xiàn); 2、服務(wù)的實例并不是實時的Eureka-server中的數(shù)據(jù),而是一個本地緩存的數(shù)據(jù); 3、緩存更新根據(jù)實際需求分為全量拉取與增量拉取。

6、集群信息同步

Eureka-server端:

集群信息同步發(fā)生在Eureka-server之間,之前提到在PeerAwareInstanceRegistryImpl類中,在執(zhí)行register方法注冊微服務(wù)實例完成后,

執(zhí)行了集群信息同步方法replicateToPeers

首先,遍歷集群節(jié)點,用以給各個集群信息節(jié)點進行信息同步。最終發(fā)送http請求,請求各個EureakServer節(jié)點。

調(diào)用EurekaServer的ApplicationResource類里面的addInstance,注意EurekaClient注冊的時候,也是調(diào)的這個方法,

單獨注冊時isReplication的值為false,集群同步時為true

Eureka三級緩存

服務(wù)端的緩存機制

服務(wù)端采用三級緩存(registry,readWriteCacheMap,readOnlyCacheMap)來存儲注冊表信息。

三級緩存的目的是為了將注冊服務(wù)和獲取服務(wù)區(qū)分開,避免了高并發(fā)的同時對一個緩存的讀寫操作,有效避免讀寫沖突。保證性能。

一級緩存 = ConcurrentHashMap registry 服務(wù)一開始注冊進來的地方 二級緩存 = Loading readWriteCacheMap,本質(zhì)上是guava的緩存,包含失效機制,保存服務(wù)信息的對外輸出數(shù)據(jù)結(jié)構(gòu)。 三級緩存 = ConcurrentHashMap readOnlyCacheMap 本質(zhì)上是HashMap,無過期時間,保存服務(wù)信息的對外輸出數(shù)據(jù)結(jié)構(gòu)。

設(shè)置緩存

(1)、客戶端將服務(wù)信息注冊在一級緩存registry中。(每30s一次心跳續(xù)約)

(2)、一級緩存registry收到注冊信息后,先清空二級緩存readWriteCacheMap中的注冊信息,然后在同步新數(shù)據(jù)給readWriteCacheMap二級緩存。

(3)、二級緩存按照30s一次的頻率給三級緩存readOnlyCacheMap同步數(shù)據(jù)

緩存獲取

(4)、其他的客戶端連接注冊中心Server 30s一次的頻率從三級緩存readOnlyCacheMap中獲取,如果readOnlyCacheMap中獲取不到,則直接去一級緩存registry中獲取。

緩存更新

(5)、一級緩存中默認(rèn)每隔60s檢查服務(wù)續(xù)期,如果90秒內(nèi)服務(wù)還沒有續(xù)期,則刪除注冊信息。同時同步給二級三級緩存。

(6)、服務(wù)下線時,一級緩存registry中的注冊信息刪除,同時刪除二級緩存的數(shù)據(jù)。30s后二級同步三級緩存時發(fā)現(xiàn)二級緩存已失效,則刪除三級緩存的注冊表信息。則會期間會有時間的延遲。

(7)、二級緩存的默認(rèn)有效期是180s(3min),3min后數(shù)據(jù)會失效,然后二級緩存數(shù)據(jù)清空。

三級緩存的弊端:

三級緩存的問題很明顯,就是服務(wù)下線之后,不能及時通知到三級緩存中,注冊信息的獲取者(客戶端)拿到的注冊信息不是實時的。(當(dāng)讓客戶端的獲取也不是實時的,要間隔30s才會去主動獲?。?/p>

柚子快報邀請碼778899分享:云原生 Eureka處理流程

http://yzkb.51969.com/

推薦文章

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/18873247.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄