自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

記一次JVM Full GC 引發(fā)的線上故障,真是坑!

開發(fā) 前端
這篇文章給大家聊一次線上生產(chǎn)系統(tǒng)事故的解決經(jīng)歷,其背后代表的是線上生產(chǎn)系統(tǒng)的JVM FullGC可能引發(fā)的嚴(yán)重故障。

?

一、業(yè)務(wù)場景介紹

先簡單說說線上生產(chǎn)系統(tǒng)的一個背景,因為僅僅是文章作為案例來講,所以弱化大量的業(yè)務(wù)背景。

簡單來說,這是一套分布式系統(tǒng),系統(tǒng)A需要將一個非常核心以及關(guān)鍵的數(shù)據(jù)通過網(wǎng)絡(luò)請求,傳輸給另外一個系統(tǒng)B。

所以這里其實就考慮到了一個問題,如果系統(tǒng)A剛剛將核心數(shù)據(jù)傳遞給了系統(tǒng)B,結(jié)果系統(tǒng)B莫名其妙宕機(jī)了,豈不是會導(dǎo)致數(shù)據(jù)丟失?

所以在這個分布式系統(tǒng)的架構(gòu)設(shè)計中,采取了非常經(jīng)典的一個Quorum算法。

這個算法簡單來說,就是系統(tǒng)B必須要部署奇數(shù)個節(jié)點(diǎn),比如說至少部署3臺機(jī)器,或者是5臺機(jī)器,7臺機(jī)器,類似這樣子。

然后系統(tǒng)A每次傳輸一個數(shù)據(jù)給系統(tǒng),都必須要對系統(tǒng)B部署的全部機(jī)器都發(fā)送請求,將一份數(shù)據(jù)傳輸給系統(tǒng)B部署的所有機(jī)器。

要判定系統(tǒng)A對系統(tǒng)B的一次數(shù)據(jù)寫是成功的,要求系統(tǒng)A必須在指定時間范圍內(nèi)對超過Quorum數(shù)量的系統(tǒng)B所在機(jī)器傳輸成功。

舉個例子,假設(shè)系統(tǒng)B部署了3臺機(jī)器,那么他的Quorum數(shù)量就是:3 / 2 + 1 = 2,也就是說系統(tǒng)B的Quorum數(shù)量就是:所有機(jī)器數(shù)量 / 2 + 1。

所以系統(tǒng)A要判定一個核心數(shù)據(jù)是否寫成功,如果系統(tǒng)B一共部署了3臺機(jī)器的話,那么系統(tǒng)A必須在指定時間內(nèi)收到2臺系統(tǒng)B所在機(jī)器返回的寫成功的響應(yīng)。

此時系統(tǒng)A才能認(rèn)為這條數(shù)據(jù)對系統(tǒng)B是寫成功了。這個就是所謂的Quorum機(jī)制。

也就是說,分布式架構(gòu)下,系統(tǒng)之間傳輸數(shù)據(jù),一個系統(tǒng)要確保自己給另外一個系統(tǒng)傳輸?shù)臄?shù)據(jù)不會丟失,必須要在指定時間內(nèi),收到另外一個系統(tǒng)Quorum(大多數(shù))數(shù)量的機(jī)器響應(yīng)說寫成功。

這套機(jī)制實際上在很多分布式系統(tǒng)、中間件系統(tǒng)中都有非常廣泛的使用,我們線上的分布式系統(tǒng)也是采用了這個Quorum機(jī)制在兩個系統(tǒng)之間傳輸數(shù)據(jù)。

給大家上一張圖,一起來看一下這套架構(gòu)長啥樣。

如上圖所示,圖中很清晰的展示了系統(tǒng)A和系統(tǒng)B之間傳輸一份數(shù)據(jù)時的Quorum機(jī)制。

接下來,我們用代碼給大家展示一下,上面的Quorum寫機(jī)制在代碼層面大概是什么樣子的。

PS:因為實際這套機(jī)制涉及大量的底層網(wǎng)絡(luò)傳輸、通信、容錯、優(yōu)化的東西,所以下面代碼經(jīng)過了大幅度簡化,僅僅表達(dá)出了一個核心的意思。

上面就是經(jīng)過大幅精簡后的代碼,不過核心的意思是表達(dá)清晰了。大家可以仔細(xì)看兩遍,其實還是很容易弄懂的。

這段代碼其實含義很簡單,說白了就是異步開啟線程發(fā)送數(shù)據(jù)給系統(tǒng)B所有的機(jī)器,同時進(jìn)入一個while循環(huán)等待系統(tǒng)B的Quorum數(shù)量的機(jī)器返回響應(yīng)結(jié)果。

如果超過指定超時時間還沒收到預(yù)期數(shù)量的機(jī)器返回結(jié)果,那么就判定系統(tǒng)B部署的集群出現(xiàn)故障,接著讓系統(tǒng)A直接退出,相當(dāng)于系統(tǒng)A宕機(jī)。

整個代碼,就是這么個意思!

二、問題凸現(xiàn)

光是看代碼其實沒啥難的,但是問題就在于線上運(yùn)行的時候,可不是跟你寫代碼的時候想的一樣簡單。

有一次線上生產(chǎn)系統(tǒng)運(yùn)行的過程中,整體系統(tǒng)負(fù)載都很平穩(wěn),本來是不應(yīng)該有什么問題,但是結(jié)果突然收到報警,說系統(tǒng)A突然宕機(jī)了。

然后就開始進(jìn)行排查,左排查右排查,發(fā)現(xiàn)系統(tǒng)B集群都好好的,不應(yīng)該有問題。

然后再查查系統(tǒng)A,發(fā)現(xiàn)系統(tǒng)A別的地方也沒什么問題。

最后結(jié)合系統(tǒng)A自身的日志,以及系統(tǒng)A的JVM FullGC進(jìn)行垃圾回收的日志,我們才算是搞清楚了具體的故障原因。

三、定位問題

其實原因非常的簡單,就是系統(tǒng)A在線上運(yùn)行一段時間后,會偶發(fā)性的進(jìn)行長時間Stop the World的JVM FullGC,也就是大面積垃圾回收。

但是,此時會造成系統(tǒng)A內(nèi)部的工作線程大量的卡頓,不再工作。要等JVM FullGC結(jié)束之后,工作線程才會恢復(fù)運(yùn)作。

我們來看下面那個代碼片段:

但是這種系統(tǒng)A的莫名宕機(jī)是不正確的,因為如果沒有JVM FullGC,本來上面那個if語句是不會成立的。

他會停頓1秒鐘進(jìn)入下一輪while循環(huán),接著就可以收到系統(tǒng)B返回的Quorum數(shù)量的結(jié)果,這個while循環(huán)就可以中斷,繼續(xù)運(yùn)行了。

結(jié)果因為出現(xiàn)了JVM FullGC卡頓了幾十秒,導(dǎo)致莫名其妙就觸發(fā)了if判斷的執(zhí)行,系統(tǒng)A莫名其妙就退出宕機(jī)了。

所以,線上的JVM FullGC導(dǎo)致的系統(tǒng)長時間卡頓,真是造成系統(tǒng)不穩(wěn)定運(yùn)行的隱形殺手之一??!

四、解決問題

至于上述代碼穩(wěn)定性的優(yōu)化,也很簡單。我們只要在代碼里加入一些東西,監(jiān)控一下上述代碼中是否發(fā)生了JVM FullGC。

如果發(fā)生了JVM FullGC,就自動延長expireTime就可以了。

比如下面代碼的改進(jìn):

通過上述代碼的改進(jìn),就可以有效的優(yōu)化線上系統(tǒng)的穩(wěn)定性,保證其在JVM FullGC發(fā)生的情況下,也不會隨意出現(xiàn)異常宕機(jī)退出的情況了。?

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2024-03-11 08:51:08

JVMSWAP內(nèi)存

2019-09-10 10:31:10

JVM排查解決

2021-05-13 08:51:20

GC問題排查

2020-06-12 13:26:03

線程池故障日志

2022-01-07 11:48:59

RabbitMQGolang 項目

2021-08-20 11:35:04

服務(wù)運(yùn)維 故障

2022-11-29 21:26:26

跨域配置

2023-01-04 18:32:31

線上服務(wù)代碼

2021-01-22 05:35:19

Lvm模塊Multipath

2021-12-02 07:50:30

NFS故障內(nèi)存

2020-11-16 07:19:17

線上函數(shù)性能

2021-01-20 13:54:34

Kafka數(shù)據(jù)Java

2021-01-08 13:52:15

Consul微服務(wù)服務(wù)注冊中心

2021-11-23 21:21:07

線上排查服務(wù)

2019-01-16 09:20:42

架構(gòu)設(shè)計JVM FullGC宕機(jī)事故

2021-04-12 09:36:14

JVM生產(chǎn)問題JVM FULL GC

2021-05-26 11:06:06

Kubernetes網(wǎng)絡(luò)故障集群節(jié)點(diǎn)

2021-12-06 17:21:05

異常報錯故障

2021-11-01 17:29:02

Windows系統(tǒng)Fork

2017-09-01 09:17:51

DNS緩存慘案
點(diǎn)贊
收藏

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