WebSocket 服務掛掉問題記錄

caohaoyu發表於2019-05-22

一、背景

之前使用websocket服務為H5頁面進行實時資料推送,突然有一天產品給我反饋,說該頁面的實時重新整理功能失效了,於是開始進行排查和處理,並將過程記錄下來。

這個服務是有監控程式的,每分鐘檢查一次websocket是否正常,不正常的話會將程式全部殺掉進行重啟。

當天接到反饋後,我看了下服務,監控程式是正常的,會對websocket進行重啟,但每次重啟過後不超過30s,websocket的master節點就又掛了。

情況就是這樣的,下面進入排查流程。

二、master節點為什麼會掛掉?

官網上有列舉以下三種情況會導致無法提供服務:

(1)系統負載過大swoole無法申請到記憶體而掛掉
(2)swoole底層發生段錯誤
(3)Server佔用記憶體過大被核心Kill,或者被某些程式誤殺

但是根據當前環境,並不符合上述情況,所以這個問題暫時還沒有找到具體的原因。

三、根據日誌報錯解決

(1)首先看了下nginx的error.log,發現大量報錯:

13247#0: *176909901 connect() failed (111: Connection refused) while connecting to upstream,

看了下nginx配置,可以看出一開始的配置是很小的,所以對幾個配置進行增大

worker_processes  1;  //worker角色的程式個數
worker_rlimit_nofile 1024;// 更改worker程式的最大開啟檔案數限制。
worker_connections  1024;//每一個worker程式能併發處理(發起)的最大連線數(包含所有連線數)

(2)swoole自帶的log日誌中也有很多報錯:

ERROR   swServer_master_onAccept (ERROR 502): accept() failed. Error: Too many open files[24]

(3)還有在程式啟動會輸出:

WARN    swServer_start_check: serv->max_conn is exceed the maximum value[1024].

官方解釋為啥會出現這個報錯,所以說明當前的問題就是因為ulimit -n設定的過低導致的問題:

max_connection最大不得超過作業系統ulimit -n的值,否則會報一條警告資訊,並重置為ulimit -n的值

綜合(2)(3)可以得出結論就出在這個ulimit -n上面了,之前也修改過這個值但實際上並沒有生效。

ulimit -n 指定同一時間最多可開啟的檔案數
vim /etc/security/limits.conf  -------永久修改
ulimit -n 1024 -----------------------即時修改,但重啟後就無效了

四、後續問題

(1)訪問量上來後,發現會出現redis偶爾連結失敗的報錯,查詢原因是因為大量建立連結導致機器上的埠都在使用中,透過調整核心引數解決。


vim /etc/sysctl.conf

編輯檔案,加入以下內容:
net.ipv4.tcp_tw_reuse = 1 //表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連線,預設為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 //表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉。

然後執行/sbin/sysctl -p讓引數生效。

(2)訂閱redis後,一段時間後會無法收到資訊。原因暫時不明,透過增加連結超時捕獲異常後重新建立訂閱請求解決。

ini_set('default_socket_timeout', 10);

五、後記

整理文件的同時就是將解決問題的過程重新覆盤一遍,以後解決這種問題的思路就會比較清晰了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章