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

面試官:高并發(fā)下重啟服務(wù),接口調(diào)用老是超時(shí),你有什么解決辦法?

開發(fā) 架構(gòu)
「了解 Dubbo 服務(wù)預(yù)熱過程嗎?詳細(xì)聊聊它的原理?!惯@個(gè)問題朋友沒有很好答出來,因?yàn)橹耙矝]了解過。說實(shí)話一開始我只是大概知道這塊預(yù)熱的代碼位于何處,但是原理什么的還是沒有仔細(xì)去了解。

[[354247]]

 Hello,大家好,我是樓下小黑哥~

今天文章內(nèi)容來自一位朋友出去面試碰到的問題:

「了解 Dubbo 服務(wù)預(yù)熱過程嗎?詳細(xì)聊聊它的原理?!?/p>

這個(gè)問題朋友沒有很好答出來,因?yàn)橹耙矝]了解過。說實(shí)話一開始我只是大概知道這塊預(yù)熱的代碼位于何處,但是原理什么的還是沒有仔細(xì)去了解。

所以這次仔細(xì)去看了下代碼,查了一些 Github 這塊代碼提交記錄,終于搞明白這塊的原理,跟大家一起分享下。

預(yù)熱

首先我們來看下什么是服務(wù)預(yù)熱?

先舉一個(gè)生活的中的例子,買過新車的同學(xué)應(yīng)該知道新車都有一個(gè)磨合期的,大概開個(gè)一兩千公里之后,才能達(dá)到最佳的狀態(tài)。

其實(shí)服務(wù)預(yù)熱也是這個(gè)意思,服務(wù)剛啟動(dòng)的時(shí)候?qū)⒋嬖谝欢巍改ズ掀凇梗@段期間服務(wù)運(yùn)行狀態(tài)沒有達(dá)到最佳,如果一下子將服務(wù)流量提升到平常的狀態(tài),可能會(huì)存在大量的請(qǐng)求超時(shí)或者瞬間將系統(tǒng)壓垮。

 

所以服務(wù)剛啟動(dòng)的時(shí)候我們要慢慢增加的流量,直到一段時(shí)間后增加到閾值的上限,給系統(tǒng)一個(gè)「預(yù)熱過程」,讓其運(yùn)行狀態(tài)到達(dá)最佳。

 

那為什么服務(wù)剛啟動(dòng)的時(shí)候系統(tǒng)狀態(tài)沒有到達(dá)最佳狀態(tài)?

大概原因其實(shí)如下:

Java 應(yīng)用存在一個(gè)類加載的過程,而這個(gè)過程是按需加載的。即服務(wù)剛啟動(dòng)時(shí)候,JVM 只加載了啟動(dòng)過程必需的類。

我們自己所需要的類,直到服務(wù)被調(diào)用之后才會(huì)被真正的加載。

另外對(duì)于一些「熱點(diǎn)代碼」,JVM 將會(huì)使用 JIT 編譯器編譯成本地代碼,提高運(yùn)行速度。

上面兩個(gè)過程是出于 JVM 系統(tǒng)層面的影響。

除此之外,我們服務(wù)系統(tǒng)中可能會(huì)需要一些緩存資源。剛啟動(dòng)的時(shí)候,由于資源不存在,服務(wù)需要去加載這些資源。

Dubbo 預(yù)熱實(shí)現(xiàn)方式

好了,了解完預(yù)熱是咋回事后,我們回到正題,來看下 Dubbo 是如何實(shí)現(xiàn)預(yù)熱的。

首先我們來看下 Dubbo 服務(wù)模型:

 

服務(wù)提供者啟動(dòng)之后將會(huì)把節(jié)點(diǎn)相關(guān)信息注冊(cè)到注冊(cè)中心,服務(wù)消費(fèi)者通過注冊(cè)中心就可以及時(shí)獲取所有的服務(wù)節(jié)點(diǎn)。

當(dāng)服務(wù)消費(fèi)者調(diào)用服務(wù)時(shí),內(nèi)部將會(huì)通過負(fù)載均衡組件選擇一個(gè)節(jié)點(diǎn),進(jìn)行服務(wù)調(diào)用。

如上圖所示,假設(shè) B 節(jié)點(diǎn)服務(wù)剛啟動(dòng),其需要一個(gè)預(yù)熱過程,這就需要服務(wù)消費(fèi)者逐漸將流量分發(fā)給 B 節(jié)點(diǎn)。

下面我們就從 Dubbo 源碼出發(fā),觀察服務(wù)預(yù)熱具體實(shí)現(xiàn)方式,具體源碼位于 AbstractLoadBalance#getWeight

 

ps: 當(dāng)前源碼 Dubbo 版本為2.7.4,低于這個(gè)版本代碼實(shí)現(xiàn)存在少量差異,詳情見下文。

這段代碼主要分為三步:

  1. 獲取服務(wù)提供者啟動(dòng)時(shí)間 timestamp
  2. 使用當(dāng)前時(shí)間減去服務(wù)提供者啟動(dòng)時(shí)間,計(jì)算服務(wù)提供者已運(yùn)行時(shí)間 uptime
  3. 根據(jù)已運(yùn)行時(shí)間動(dòng)態(tài)計(jì)算服務(wù)預(yù)熱過程的權(quán)重

第三步動(dòng)態(tài)權(quán)重計(jì)算方法如下:

 

這里計(jì)算方式其實(shí)很簡(jiǎn)單,簡(jiǎn)單來說服務(wù)運(yùn)行時(shí)間越久,權(quán)重越高,直到正常權(quán)重。

假如服務(wù)提供者已運(yùn)行 1 分鐘,那么 weight 最終結(jié)果為 10 。

假如服務(wù)提供者已運(yùn)行 5 分鐘,那么 weight 最終結(jié)果為 50 。

假如服務(wù)提供者已運(yùn)行 11 分鐘,超過默認(rèn)預(yù)熱時(shí)間的閾值 10分 鐘,那么將不會(huì)再計(jì)算,直接返回 weight 默認(rèn)權(quán)重。

這里我們需要注意的是,Dubbo 默認(rèn)提供五種負(fù)載均衡的策略:

  • Random LoadBalance :「加權(quán)隨機(jī)」策略
  • RoundRobin LoadBalance:「加權(quán)輪詢」策略
  • LeastActive LoadBalance:「最少活躍調(diào)用數(shù)」策略
  • ConsistentHash LoadBalance:「一致性 Hash」 策略
  • ShortestResponse LoadBalance:「最短響應(yīng)時(shí)間」策略

「ShortestResponse LoadBalance」 策略小伙伴們可能會(huì)比較陌生,官方文檔中并沒有提到這個(gè)策略。

其實(shí)這個(gè)是 Dubbo 2.7.7 版本新增的負(fù)載均衡策略,官方文檔估計(jì)還沒更新。

 

ps:感興趣的小伙伴,可以去修改下官方的文檔,增加這個(gè)新的負(fù)載均衡的策略,為開源獻(xiàn)出我們的一份力量。

回到正文,從AbstractLoadBalance#getWeight調(diào)用關(guān)系可以看到,「ConsistentHash LoadBalance」 實(shí)現(xiàn)類是不支持服務(wù)預(yù)熱,這點(diǎn)需要注意一下。

 

Dubbo 預(yù)熱歷史 bug-反復(fù)橫跳雖然 Dubbo 預(yù)熱的相關(guān)代碼,總體看起來不是很難,但是歷史版本還是存在幾個(gè) Bug,導(dǎo)致預(yù)熱失效。

Dubbo 2.5.5 之前的版本

在 Dubbo 2.5.5 之前的版本,AbstractLoadBalance#getWeight實(shí)現(xiàn)方式如下:

 

這個(gè)版本跟現(xiàn)在代碼一樣,都是從節(jié)點(diǎn)的 timestamp獲取服務(wù)啟動(dòng)時(shí)間。不過這個(gè)版本存在一些問題,Dubbo 沒有把服務(wù)提供者啟動(dòng)時(shí)間傳給消費(fèi)者,導(dǎo)致這里獲取 timestamp是消費(fèi)者啟動(dòng)時(shí)間,這樣就導(dǎo)致預(yù)熱失效。

等到 Dubbo 2.5.6 ,修復(fù)這個(gè)問題,源碼如下:

 

這個(gè)版本將服務(wù)提供者啟動(dòng)時(shí)間單獨(dú)保存在 remote.timestamp 屬性中,源碼位于 ClusterUtils#mergeUrl

 

通過這種方式修復(fù)預(yù)熱失效的問題。

Dubbo 2.7.2 預(yù)熱又失效了

當(dāng) Dubbo 版本升級(jí)到 2.7.2 ,這個(gè)預(yù)熱失效 Bug 又回來了。帶來這個(gè)問題主要原因是ClusterUtils#mergeUrl 源碼中清除了remote.timestamp,轉(zhuǎn)而統(tǒng)一使用 timestamp保存服務(wù)啟動(dòng)時(shí)間。

 

但是呢,由于修改沒有徹底, AbstractLoadBalance#getWeight還是依然使用 remote.timestamp 獲取服務(wù)啟動(dòng)時(shí)間,這就導(dǎo)致預(yù)熱失效。

預(yù)熱代碼的隱藏 bug

這個(gè) Bug 在Dubbo 2.7.4 版本被徹底修復(fù),另外還順帶優(yōu)化了代碼中存在缺陷。

先看下原先的代碼中國(guó)缺陷,原先預(yù)熱代碼實(shí)現(xiàn)采用如下方式計(jì)算服務(wù)啟動(dòng)運(yùn)行的時(shí)間。

int uptime = (int) (System.currentTimeMillis() - timestamp);

但是這里存在一個(gè)問題,如果服務(wù)提供者與消費(fèi)者兩端時(shí)鐘是不一致,服務(wù)提供者啟動(dòng)時(shí)間很有可能會(huì)大于消費(fèi)者本地時(shí)間。

這種情況,uptime 計(jì)算結(jié)果為一個(gè)負(fù)值,這就會(huì)導(dǎo)致權(quán)重將使用配置的默認(rèn)值,預(yù)熱也失效了。

所以針對(duì)這種情況 「@aftersss」 提供了修復(fù)的方案,加入相關(guān)的判斷,當(dāng) uptime為負(fù)值的時(shí)候,直接返回權(quán)重 1。

不過在 「Code review」 過程中,「@beiwei30」 覺得不用加入額外 if 判斷,可以直接使用 Math.max兼容。

 

不過這樣修改,還是存在一個(gè)問題:Integer 精度丟失問題。

 

如果此時(shí) System.currentTimeMillis() = 1566209746000(2019-08-19 18:15:46),而 timestamp = 1561914711000(2019-07-01 01:11:51),當(dāng)兩者差值為:「4295035000」。

這是一個(gè)遠(yuǎn)大于 Integer.MAX_VALUE的值,所以在 long 轉(zhuǎn)為 int 時(shí)候精度丟失,導(dǎo)致最后實(shí)際得到 int 值為 「67704」。

而這個(gè)值小于服務(wù)預(yù)熱的默認(rèn)時(shí)間(10 * 60 * 1000),所以進(jìn)入動(dòng)態(tài)計(jì)算權(quán)重環(huán)節(jié),最終將得到一個(gè)比較小的權(quán)重,這就導(dǎo)致「假預(yù)熱」。

所以最后還是采用 「@aftersss」 修復(fù)的方案,采用 long 類型存儲(chǔ)時(shí)間戳計(jì)算結(jié)果,最終優(yōu)化代碼如下:

 

總結(jié)

今天的文章主要介紹了服務(wù)預(yù)熱的作用,以及 Dubbo 服務(wù)預(yù)熱的實(shí)現(xiàn)方式。

這個(gè)實(shí)現(xiàn)方式整體來說不是很難,簡(jiǎn)單來說就是隨著運(yùn)行時(shí)間逐漸提高權(quán)重,從而增加服務(wù)節(jié)點(diǎn)的流量。

如果你當(dāng)前使用框架并沒有這個(gè)功能,而你正需要服務(wù)預(yù)熱,可以參考 Dubbo 的實(shí)現(xiàn)方式。

另外由于 Dubbo 歷史版本存在一些 Bug,如果各小伙伴需要使用服務(wù)預(yù)熱功能,需要注意避免使用以下版本:

  • 「Dubbo 2.5.5 之前的版本」
  • 「Dubbo 2.7.2/ 2.7.3」

好了,今天的文章就到這里了~我是樓下小黑哥,你知道的越多,你不知道的就越多。

我們下周再見~

相關(guān)資料https://github.com/apache/dubbo/issues/6242

https://github.com/apache/dubbo/issues/306

https://github.com/apache/dubbo/pull/4870

本文轉(zhuǎn)載自微信公眾號(hào)「程序通事」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序通事眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 程序通事
相關(guān)推薦

2021-08-05 12:41:57

高并發(fā)性能CAS

2024-09-29 00:00:00

高并發(fā)交易所宕機(jī)

2025-04-01 00:00:00

項(xiàng)目CRUD單例模式

2024-09-09 08:30:56

代碼

2009-12-22 14:16:01

WCF連接服務(wù)超時(shí)

2024-09-03 09:31:41

微服務(wù)面試官系統(tǒng)

2021-12-23 07:11:31

開發(fā)

2015-08-13 10:29:12

面試面試官

2022-02-14 20:53:33

開源庫開發(fā)代碼

2024-03-12 14:36:44

微服務(wù)HTTPRPC

2025-03-10 11:48:22

項(xiàng)目服務(wù)設(shè)計(jì)

2025-04-29 02:00:00

高并發(fā)系統(tǒng)場(chǎng)景

2019-06-06 10:55:02

JDK高并發(fā)框架

2021-12-28 09:50:18

Redis單線程高并發(fā)

2020-10-15 06:26:24

高并發(fā)場(chǎng)景冰河

2023-12-13 13:31:00

useEffect對(duì)象瀏覽器

2021-07-06 07:27:45

React元素屬性

2023-02-17 08:10:24

2021-12-20 10:30:33

forforEach前端

2024-07-26 08:10:10

點(diǎn)贊
收藏

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

主站蜘蛛池模板: 97成人精品 | 国产精品夜间视频香蕉 | 一区二区免费看 | 天天干b| 一区中文字幕 | 91免费看片 | 欧美一区二区三区四区五区无卡码 | 欧美日本韩国一区二区 | 国产极品车模吞精高潮呻吟 | 国产日韩一区二区三免费 | 黄色精品 | 午夜电影日韩 | 亚洲精品www久久久 www.蜜桃av | 精品91av| 欧美精品日韩精品 | 国产日韩一区二区三免费高清 | 国产欧美精品一区二区色综合 | 日韩久久精品视频 | 97国产精品视频人人做人人爱 | 欧美久 | 九色av | 日韩成人专区 | 国产成人精品一区 | 一区二区三区国产精品 | 免费能直接在线观看黄的视频 | 亚洲成人激情在线观看 | 亚洲精品一区二区在线观看 | 黄色成人免费看 | 欧美日韩在线一区二区三区 | 亚洲国产精品va在线看黑人 | 午夜精品福利视频 | 中文字幕1区 | 欧美中文字幕一区二区三区亚洲 | 国产探花在线精品一区二区 | 毛色毛片免费看 | 91婷婷韩国欧美一区二区 | 久久久久av | 免费视频一区二区三区在线观看 | 亚洲一区二区三区在线视频 | 久久精品国产久精国产 | 一级在线观看 |