成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我也是醉了,Eureka 延遲注冊(cè)還有這個(gè)坑!

開(kāi)發(fā) 架構(gòu)
即便我們把所有途徑都封死了,但是發(fā)送心跳的線程仍然會(huì)去注冊(cè),所以這個(gè)延遲注冊(cè)的時(shí)間最多也不會(huì)超過(guò) 30 秒,即便配置的延遲時(shí)間超過(guò) 30 秒。

Eureka 有個(gè)延遲注冊(cè)的功能,也就是在服務(wù)啟動(dòng)成功之后不立刻注冊(cè)到 Eureka Server,而是延遲一段時(shí)間再去注冊(cè),這樣做的主要目的是因?yàn)殡m然服務(wù)啟動(dòng)成功了,可能還有一些框架或者業(yè)務(wù)的代碼沒(méi)有初始化完成,可能會(huì)導(dǎo)致調(diào)用的報(bào)錯(cuò),所以需要延遲注冊(cè)。

但是發(fā)現(xiàn),然并卵啊,好像這個(gè)延遲注冊(cè)并沒(méi)有生效,也是開(kāi)始了排查之路。

延遲注冊(cè)

首先,延遲注冊(cè)的功能主要依賴這兩個(gè)參數(shù),eureka.client.initial-instance-info-replication-interval-seconds?代表第一次初始化延遲注冊(cè)的時(shí)間間隔,eureka.client.instance-info-replication-interval-seconds則代表后續(xù)同步注冊(cè)的時(shí)間間隔。

eureka.client.initial-instance-info-replication-interval-seconds=40 //默認(rèn)40秒
eureka.client.instance-info-replication-interval-seconds=30 //默認(rèn)30秒

我們從源碼先來(lái)看是怎么做到延遲注冊(cè)的,先看 DiscoveryClient? 的 initScheduledTasks ,這里創(chuàng)建了同步注冊(cè)到 Eureka Server 的定時(shí)任務(wù)。

圖片

之后調(diào)用 start 方法創(chuàng)建定時(shí)任務(wù),并且延遲 40 秒執(zhí)行,也就是我們達(dá)到的延遲注冊(cè)的效果。

圖片

圖片

默認(rèn)的第一次注冊(cè),也就是延遲注冊(cè)的時(shí)間是 40 秒,之后每 30 秒會(huì)同步注冊(cè)信息。

圖片

但是,即便我們配置了這倆屬性,發(fā)現(xiàn)好像沒(méi)什么卵用,接下來(lái)我們要排查下到底是為啥捏?

第一個(gè)問(wèn)題

我發(fā)現(xiàn)在 InstanceInfoReplica 中存在這樣一段終止當(dāng)前線程池任務(wù),并且直接調(diào)用 run 方法的存在,猜測(cè)失效就是他直接調(diào)用導(dǎo)致延遲任務(wù)沒(méi)有生效,因?yàn)檫@個(gè)方法的直接調(diào)用導(dǎo)致延遲注冊(cè)壓根就沒(méi)效果嘛。

圖片

看起來(lái)他存在兩個(gè)調(diào)用,第一個(gè)是registerHealthCheck?,當(dāng)存在這個(gè)健康檢查什么玩意兒的時(shí)候就會(huì)去調(diào)用onDemandUpdate。

圖片

經(jīng)過(guò)排查我們發(fā)現(xiàn),只要配置了eureka.client.healthcheck.enabled=true?,就會(huì)創(chuàng)建 HealthCheckHandler?的實(shí)例出來(lái),默認(rèn)情況下他是false的,所以應(yīng)該是對(duì)我們沒(méi)有影響的。

圖片

這里需要特別說(shuō)明一下 eureka.client.healthcheck.enabled ?的作用,默認(rèn) Eureka 根據(jù)心跳來(lái)決定應(yīng)用的狀態(tài),如果是這個(gè)屬性配置成 true的話,則是會(huì)根據(jù) Spring Boot Actuator 來(lái)決定,而不是心跳了。

比如我們可以實(shí)現(xiàn) HealthIndicator?接口,自己寫(xiě)一個(gè)Controller來(lái)動(dòng)態(tài)改變服務(wù)的狀態(tài)

@RestController
public class ControllerTest {
@Autowired
private HealthChecker healthChecker;

@RequestMapping("/change")
public String test(Boolean flag) {
healthChecker.setUp(new AtomicBoolean(flag));
return "success";
}

}

實(shí)現(xiàn)HealthChecker,這樣會(huì)發(fā)現(xiàn)啟動(dòng)、下線服務(wù) Eureka Server 的狀態(tài)不會(huì)變成 Down,只有通過(guò)調(diào)用接口手動(dòng)改變應(yīng)用狀態(tài) Server 的狀態(tài)才會(huì)發(fā)生改變,大家可以自行測(cè)試。

@Component
public class HealthChecker extends EurekaHealthIndicator implements HealthIndicator {
private AtomicBoolean up = new AtomicBoolean(true);

public HealthChecker(EurekaClient eurekaClient, EurekaInstanceConfig instanceConfig, EurekaClientConfig clientConfig) {
super(eurekaClient, instanceConfig, clientConfig);
}

@Override
public Health health() {
if(up.get()){
return Health.up().build();
}else{
return Health.down().build();
}
}

第二個(gè)問(wèn)題

第一個(gè)問(wèn)題我們找到了,發(fā)現(xiàn)他不是導(dǎo)致我們問(wèn)題的根因,于是繼續(xù)排查。

發(fā)現(xiàn)第二個(gè)調(diào)用,在DiscoveryClient注冊(cè)了狀態(tài)事件變更的監(jiān)聽(tīng),如果狀態(tài)發(fā)生變更,也會(huì)去調(diào)用 onDemandUpdate ,影響延遲注冊(cè)的效果。

這里存在一個(gè)配置項(xiàng)onDemandUpdateStatusChange?,默認(rèn)是true,所以應(yīng)該是他沒(méi)錯(cuò)了。

圖片

進(jìn)入StatusChangeListener,找到了一個(gè)調(diào)用。

圖片

就是通過(guò)setInstanceStatus方法觸發(fā)的事件通知。

圖片

這里存在 6 個(gè)調(diào)用,一一排查,通過(guò)源碼找啊找,最終定位到服務(wù)啟動(dòng)自動(dòng)裝配的地方,在這里去修改服務(wù)狀態(tài)為 UP?,然后觸發(fā)事件通知,啟動(dòng) start? 方法調(diào)用register方法。

圖片

繼續(xù)調(diào)用,修改應(yīng)用為上線UP狀態(tài)。

圖片

由此我們知道,只要服務(wù)啟動(dòng)成功,就會(huì)觸發(fā)事件通知,所以這個(gè)基本上是啟動(dòng)成功立刻就會(huì)去注冊(cè)到 Eureka Server,這就會(huì)導(dǎo)致延遲注冊(cè)的失效,從啟動(dòng)日志也能直觀的看到這個(gè)效果。

圖片

驗(yàn)證

為了驗(yàn)證我的猜想,我把這兩個(gè)配置同時(shí)配置成false,并且把延遲注冊(cè)的時(shí)間調(diào)整到非常大。

eureka.client.healthcheck.enabled=false
eureka.client.onDemandUpdateStatusChange=false
eureka.client.initial-instance-info-replication-interval-seconds=9999999 //默認(rèn)40秒
eureka.client.instance-info-replication-interval-seconds=999999 //默認(rèn)30秒

但是,但是?。?!

發(fā)現(xiàn)過(guò)了幾十秒之后,還是注冊(cè)到 Server 了,真的是醉了。。。

那就繼續(xù)看吧。

再看下注冊(cè)方法,可能不止一個(gè)地方存在調(diào)用,我們發(fā)現(xiàn)果然如此,有 3 個(gè)地方都調(diào)用了注冊(cè)方法。

圖片

第一個(gè)調(diào)用在DiscoveryClient?注入的時(shí)候,這個(gè)看了下,clientConfig.shouldEnforceRegistrationAtInit()?默認(rèn)是false,方法不會(huì)進(jìn)來(lái),不管他了。

圖片

那么繼續(xù)看第二個(gè)調(diào)用,第二個(gè)調(diào)用你看renew方法,這一看我們就知道了,這不就是心跳嗎?!

發(fā)送心跳如果返回NOT_FOUND,就會(huì)去注冊(cè)了啊。

圖片

圖片

感覺(jué)已經(jīng)接近真相了,去找下 Server 心跳的源碼,根據(jù)調(diào)用的路徑找到源碼位于InstanceResource中。

可以看到第一次注冊(cè)的時(shí)候從注冊(cè)表拿到的實(shí)例信息是空的,所以直接返回了 false,就會(huì)返回 NOT FOUND 了。

圖片

看registry.renew?方法,最終會(huì)調(diào)用到AbstractInstanceRegistry?中,初始化的時(shí)候注冊(cè)表registry?肯定沒(méi)有當(dāng)前實(shí)例的信息,所以拿到是空的,返回了false,最終就返回了NOT_FOUND。

圖片

因此,雖然我們把這兩個(gè)參數(shù)都設(shè)置成了false,但是由于心跳默認(rèn) 30 秒一次,所以最終我們發(fā)現(xiàn)配置的超級(jí)大的延遲注冊(cè)的時(shí)間并沒(méi)有完全生效。

總結(jié)

OK,到此,延遲注冊(cè)不生效的原因找到了,我們做一個(gè)總結(jié)。

默認(rèn)情況下,配置了延遲注冊(cè)的時(shí)間并不會(huì)生效,因?yàn)槭录O(jiān)聽(tīng)默認(rèn)是true,服務(wù)啟動(dòng)之后就會(huì)立刻注冊(cè)到 Eureka Server。

如果需要延遲注冊(cè)生效,必須 eureka.client.healthcheck.enabled ?、eureka.client.onDemandUpdateStatusChange? 都為false。

即便我們把所有途徑都封死了,但是發(fā)送心跳的線程仍然會(huì)去注冊(cè),所以這個(gè)延遲注冊(cè)的時(shí)間最多也不會(huì)超過(guò) 30 秒,即便配置的延遲時(shí)間超過(guò) 30 秒。

責(zé)任編輯:武曉燕 來(lái)源: 艾小仙
相關(guān)推薦

2023-10-30 08:16:33

數(shù)據(jù)庫(kù)插件Mybatis

2022-03-21 08:55:53

RocketMQ客戶端過(guò)濾機(jī)制

2025-04-08 08:12:26

Next.js組件ChatGPT

2021-09-03 11:15:18

場(chǎng)景sql配置

2021-08-10 10:48:39

拷貝代碼架構(gòu)耦合

2022-10-17 08:17:47

位掩碼Java變量

2024-10-06 13:41:25

2022-06-20 10:00:57

Python工具包代碼

2022-01-03 20:13:08

Gointerface 面試

2021-09-30 08:40:28

Oracle數(shù)據(jù)庫(kù)后端開(kāi)發(fā)

2018-07-12 14:59:44

獵網(wǎng)

2013-11-29 13:05:07

程序員工作

2022-01-07 13:36:00

MySQL數(shù)據(jù)庫(kù)分頁(yè)

2021-02-24 09:43:36

MySQL數(shù)據(jù)庫(kù)雙引號(hào)

2020-03-12 15:00:44

JavaSpring依賴

2018-09-13 10:59:30

Redis鍵值存儲(chǔ)

2017-06-16 16:16:36

庫(kù)存扣減查詢

2023-05-31 07:57:12

筆記本電腦信譽(yù)度

2025-03-31 08:35:00

Eureka微服務(wù)架構(gòu)

2023-12-01 07:38:33

微服務(wù)訂單服務(wù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 99久久久99久久国产片鸭王 | 欧美久久精品一级黑人c片 91免费在线视频 | 欧美一区二区免费电影 | 欧美精品免费观看二区 | 国产中文字幕亚洲 | 9999在线视频 | 91精品国产99| 狠狠色综合欧美激情 | 久久久精彩视频 | 久久久久久久久久久蜜桃 | 一区二区三区在线播放 | 久久青视频 | 一区二区在线免费观看 | 日韩成人在线观看 | 色精品 | 古装人性做爰av网站 | 一级欧美| 国产精品久久久久久久久久免费看 | 欧美一区二区三区精品免费 | 亚洲一卡二卡 | 欧美中文字幕在线观看 | 精品欧美乱码久久久久久1区2区 | 最新日韩在线 | 亚洲不卡一 | 精品欧美一区二区中文字幕视频 | 亚洲视频一区在线观看 | 国产成人91视频 | 91香蕉| 国产一区二区免费 | 久久久久久国产精品 | 欧美中文字幕 | 久热国产精品视频 | 日韩网站免费观看 | 免费亚洲一区二区 | 五月天婷婷狠狠 | 一级黄片一级毛片 | 亚洲欧美在线观看 | 亚洲精品1区2区3区 91免费看片 | 午夜精品一区二区三区在线观看 | 欧美精品在线免费观看 | 精品成人|