一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】

石杉的架構筆記發表於2018-12-20

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100)

週一至週五早8點半!精品技術文章準時送上!


這篇文章給大家聊一次線上生產系統事故的解決經歷,其背後代表的是線上生產系統的JVM FullGC可能引發的嚴重故障。


一、業務場景介紹

先簡單說說線上生產系統的一個背景,因為僅僅是文章作為案例來講,所以弱化大量的業務背景。

簡單來說,這是一套分散式系統,系統A需要將一個非常核心以及關鍵的資料通過網路請求,傳輸給另外一個系統B。

所以這裡其實就考慮到了一個問題,如果系統A剛剛將核心資料傳遞給了系統B,結果系統B莫名其妙當機了,豈不是會導致資料丟失?

所以在這個分散式系統的架構設計中,採取了非常經典的一個Quorum演算法

這個演算法簡單來說,就是系統B必須要部署奇數個節點,比如說至少部署3臺機器,或者是5臺機器,7臺機器,類似這樣子。

然後系統A每次傳輸一個資料給系統,都必須要對系統B部署的全部機器都傳送請求,將一份資料傳輸給系統B部署的所有機器。

要判定系統A對系統B的一次資料寫是成功的,要求系統A必須在指定時間範圍內對超過Quorum數量的系統B所在機器傳輸成功。

舉個例子,假設系統B部署了3臺機器,那麼他的Quorum數量就是:3 / 2 + 1 = 2,也就是說系統B的Quorum數量就是:所有機器數量 / 2 + 1。

所以系統A要判定一個核心資料是否寫成功,如果系統B一共部署了3臺機器的話,那麼系統A必須在指定時間內收到2臺系統B所在機器返回的寫成功的響應。

此時系統A才能認為這條資料對系統B是寫成功了。這個就是所謂的Quorum機制。

也就是說,分散式架構下,系統之間傳輸資料,一個系統要確保自己給另外一個系統傳輸的資料不會丟失,必須要在指定時間內,收到另外一個系統Quorum(大多數)數量的機器響應說寫成功。

這套機制實際上在很多分散式系統、中介軟體系統中都有非常廣泛的使用,我們線上的分散式系統也是採用了這個Quorum機制在兩個系統之間傳輸資料。

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

一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】

如上圖所示,圖中很清晰的展示了系統A和系統B之間傳輸一份資料時的Quorum機制。

接下來,我們用程式碼給大家展示一下,上面的Quorum寫機制在程式碼層面大概是什麼樣子的。

PS:因為實際這套機制涉及大量的底層網路傳輸、通訊、容錯、優化的東西,所以下面程式碼經過了大幅度簡化,僅僅表達出了一個核心的意思。

一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】


上面就是經過大幅精簡後的程式碼,不過核心的意思是表達清晰了。大家可以仔細看兩遍,其實還是很容易弄懂的。

這段程式碼其實含義很簡單,說白了就是非同步開啟執行緒傳送資料給系統B所有的機器,同時進入一個while迴圈等待系統B的Quorum數量的機器返回響應結果。

如果超過指定超時時間還沒收到預期數量的機器返回結果,那麼就判定系統B部署的叢集出現故障,接著讓系統A直接退出,相當於系統A當機。

整個程式碼,就是這麼個意思!


二、問題凸現

光是看程式碼其實沒啥難的,但是問題就在於線上執行的時候,可不是跟你寫程式碼的時候想的一樣簡單。

有一次線上生產系統執行的過程中,整體系統負載都很平穩,本來是不應該有什麼問題,但是結果突然收到報警,說系統A突然當機了。

然後就開始進行排查,左排查右排查,發現系統B叢集都好好的,不應該有問題。

然後再查查系統A,發現系統A別的地方也沒什麼問題。

最後結合系統A自身的日誌,以及系統A的JVM FullGC進行垃圾回收的日誌,我們才算是搞清楚了具體的故障原因。


三、定位問題

其實原因非常的簡單,就是系統A線上上執行一段時間後,會偶發性的進行長時間Stop the World的JVM FullGC,也就是大面積垃圾回收。

但是,此時會造成系統A內部的工作執行緒大量的卡頓,不再工作。要等JVM FullGC結束之後,工作執行緒才會恢復運作。

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

一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】

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

他會停頓1秒鐘進入下一輪while迴圈,接著就可以收到系統B返回的Quorum數量的結果,這個while迴圈就可以中斷,繼續執行了。

結果因為出現了JVM FullGC卡頓了幾十秒,導致莫名其妙就觸發了if判斷的執行,系統A莫名其妙就退出當機了。

所以,線上的JVM FullGC導致的系統長時間卡頓,真是造成系統不穩定執行的隱形殺手之一啊!


四、解決問題

至於上述程式碼穩定性的優化,也很簡單。我們只要在程式碼里加入一些東西,監控一下上述程式碼中是否發生了JVM FullGC。

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

比如下面程式碼的改進:

一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】

通過上述程式碼的改進,就可以有效的優化線上系統的穩定性,保證其在JVM FullGC發生的情況下,也不會隨意出現異常當機退出的情況了。

END




如有收穫,請幫忙轉發,您的鼓勵是作者最大的動力,謝謝!


一大波微服務、分散式、高併發、高可用的原創系列文章正在路上

歡迎掃描下方二維碼,持續關注:

一次JVM FullGC的背後,竟隱藏著驚心動魄的線上生產事故!【石杉的架構筆記】

石杉的架構筆記(id:shishan100)

十餘年BAT架構經驗傾囊相授


推薦閱讀:

1、拜託!面試請不要再問我Spring Cloud底層原理

2、【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?

3、【效能優化之道】每秒上萬併發下的Spring Cloud引數優化實戰

4、微服務架構如何保障雙11狂歡下的99.99%高可用

5、兄弟,用大白話告訴你小白都能聽懂的Hadoop架構原理

6、大規模叢集下Hadoop NameNode如何承載每秒上千次的高併發訪問

7、【效能優化的祕密】Hadoop如何將TB級大檔案的上傳效能優化上百倍

8、拜託,面試請不要再問我TCC分散式事務的實現原理坑爹呀!

9、【坑爹呀!】最終一致性分散式事務如何保障實際生產中99.99%高可用?

10、拜託,面試請不要再問我Redis分散式鎖的實現原理!

11、【眼前一亮!】看Hadoop底層演算法如何優雅的將大規模叢集效能提升10倍以上?

12、億級流量系統架構之如何支撐百億級資料的儲存與計算

13、億級流量系統架構之如何設計高容錯分散式計算系統

14、億級流量系統架構之如何設計承載百億流量的高效能架構

15、億級流量系統架構之如何設計每秒十萬查詢的高併發架構

16、億級流量系統架構之如何設計全鏈路99.99%高可用架構

17、七張圖徹底講清楚ZooKeeper分散式鎖的實現原理

18、大白話聊聊Java併發面試問題之volatile到底是什麼?

19、大白話聊聊Java併發面試問題之Java 8如何優化CAS效能?

20、大白話聊聊Java併發面試問題之談談你對AQS的理解?

21、大白話聊聊Java併發面試問題之公平鎖與非公平鎖是啥?

22、大白話聊聊Java併發面試問題之微服務註冊中心的讀寫鎖優化

23、網際網路公司的面試官是如何360°無死角考察候選人的?(上篇)

24、網際網路公司面試官是如何360°無死角考察候選人的?(下篇)

25、Java進階面試系列之一:哥們,你們的系統架構中為什麼要引入訊息中介軟體?

26、【Java進階面試系列之二】:哥們,那你說說系統架構引入訊息中介軟體有什麼缺點?

27、【行走的Offer收割機】記一位朋友斬獲BAT技術專家Offer的面試經歷

28、【Java進階面試系列之三】哥們,訊息中介軟體在你們專案裡是如何落地的?

29、【Java進階面試系列之四】扎心!線上服務當機時,如何保證資料100%不丟失?



相關文章