背景:第五場展會開始後,併發量比較大,多次出現502錯誤。
日誌中出現了大量的如下錯誤:
發現 master服務器已經併發tcp數量達到 7000
Slave服務器併發tcp數量達到 700+
下面做了一些應急的處理方式,
1、 keepalive_timeout = 32 改成了 keepalive_timeout = 120
2、 此時發現定向到主服務器的upstream出現502的機率相當大。因此設置權重改變爲3:7
3、 結果還是不行,最後取消了負載到主服務器,僅僅使用slave服務器。
4、 效果有所改善,但是秒殺開始的時候,依然會出現502錯誤。
5、 後來停掉了聊天服務器。
6、 基於產品的需要,又開啓了聊天服務器,只不過更改了聊天服務器的發送頻率由2s到5s,但還是沒從根本上解決問題。
問題:
通過日誌分析,訪問的人數和之前的幾次訪問人數相差不多,可是這次出現了比較嚴重的502錯誤。原因暫時還未查明。
不過我通過我試着ab 測試來複現該錯誤。
通過上面的分析,只有兩個請求錯誤,還可以接受。
當我隨着加大併發量的時候,到了250個的時候,
ab -n 10000 -c 300 http://192.168.10.106:8080/tje/exhibition/chatroom
幾乎90%以上的都是502了。
下面我的處理方式,修改了一個參數
在/etc/sysctl.conf下面添加了
net.core.somaxconn = 1024
然後執行 sysctl –p 使修改生效
重啓web服務器。
測試:
依然沒問題,只是響應時間都變成5s以上了。
我看內存依然有剩餘,我試着增大了passenger_max_pool_size 由32到40 。
在執行併發 100 ,300 ,1000 。
發現併發處理能力卻沒有提高,依然每秒 170次左右,如果下降到20,處理併發能力下降。
這個值的設定依據情況而定,如果railsapp本身佔內存特別大,開大了反而不好。我保守按照80M-100M計算。
現在解決了併發出現502錯誤的問題。
那原理是什麼呢
看到網絡上很多說 修改backlog的,其實passenger在2.2.6的時候已經修改了他的backlog。提升至 1024了
而且man 2 listen查詢 瞭解到這裏的backlog實際上是完成三次握手後的tcp隊列,換句話說這裏是TCP已經建立,等待服務器accept的隊列數目。
而我們應對併發的時候,很多客戶端發送SYN j請求,服務器給與ACK j+1 應答並SYN k,客戶端需要應答ACK k+1 ,這樣,如果客戶端不應答,或者來不及應答ACK k+1 就造成了半連接,這在併發高的系統中是常見的,linux有個隊列來維持半連接,如果隊列溢出,則拒絕服務,這就是DOS工具的基本原理。
因此我們需要修改半連接隊列的長度,這裏有兩個地方,可以通過命令查看
修改這兩個值爲1024即可。不過系統對對tcp_max_syn_backlog默認爲1024了,所以只需要在 /ect/sysctl.conf後添加 net.core.somaxconn = 1024即可。