服務爲什麼會崩潰

1.概述

最近看了一篇關於熱key導致redis服務集羣掛掉的文章, 非常的精彩導致我在想當流量非常大時爲什麼redis服務會掛掉,於是我就找了大量的資料研究服務爲什麼會掛掉及其原理,服務器爲什麼會宕機等等就有了如下內容。

其實服務崩潰總結起來無非就兩種,一種是資源枯竭導致的服務崩潰,另一種就是超時引起的服務崩潰。


2.資源枯竭導致

先說第一種資源枯竭導致的服務崩潰,顧名思義就是因爲服務器的資源或者分配的資源不能滿足服務運行的需要從而引發服務崩潰。比較常見有內存溢出,磁盤滿載,帶寬不足等三種。

寫java的程序員遇到最多的估計就是內存溢出了,比如操作系統給jvm分配了2G的物理內存供程序運行使用,可能有個程序頭鐵在一段代碼中創建了循環引用的對象或者大量未能及時回收的對象,在請求量大時gc不能及時回收垃圾對象導致堆內存一直在增大超過了操作系統所分配的2G內存,此時就會觸發操作系統的kill -9信號把程序殺死這樣用戶再請求服務時就無響應了。

電商大促期間前有很多準備工作,其中有一項就是去運營商那裏購買寬帶,這是因爲在大促期間有大量用戶訪問,如果機器帶寬不足會導致服務崩潰,進而導致非常大損失。我們以一臺機器80M的寬帶爲例,經過計算能承受的最大下載速度就是10M/s, 拿單個用戶的一個請求數據大小爲10k爲例,在1s內有1024個用戶請求時需要80M的寬帶機器剛好能滿足要求,如果是1s內有2000用戶請求時需要160M的流量那麼處理完這2000個用戶的請求需要2s,如果持續30s都有2000個用戶來請求服務,那麼就需要4800M的流量處理完需要600多s那麼就會大量請求出現等待進而引發超時導致服務崩潰。


3.超時導致

第二種超時引起的服務崩潰,就是大量用戶請求服務時因爲大面積連接超時導致服務崩潰,和寬帶不足的例子很像,我們以單臺機器服務啓動單進程爲例,在一個進程中我們通常會通過線程池去處理請求,我們假設線程池中一共有1000個請求來處理請求且每個請求的響應時間爲100ms,當1s鐘有10000個請求發來時我們可以很快的處理並返回,當1s內有20000個請求發來時服務器要處理就需要2s鐘的時間了,那麼在一段持續時間20000請求來時就會積壓大量的請求不能被處理導致超時,然後後面過來的請求肯定超時,這樣服務就崩潰了。


4.總結

在真實的生產環境,崩潰的原因可能會非常複雜且是多種因素互相作用的結果,但瞭解了服務奔潰的本質後就能很快找到對應的解決方案,如萬能的增加機器,優化代碼邏輯,加入緩存等等。完畢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章