以前使用websocket服務爲H5頁面進行實時數據推送,忽然有一天產品給我反饋,說該頁面的實時刷新功能失效了,因而開始進行排查和處理,並將過程記錄下來。html
這個服務是有監控程序的,每分鐘檢查一次websocket是否正常,不正常的話會將進程所有殺掉進行重啓。nginx
當天接到反饋後,我看了下服務,監控程序是正常的,會對websocket進行重啓,但每次重啓事後不超過30s,websocket的master節點就又掛了。web
狀況就是這樣的,下面進入排查流程。redis
在官網上有列舉如下三種狀況會致使沒法提供服務:vim
(1)系統負載過大swoole沒法申請到內存而掛掉
(2)swoole底層發生段錯誤
(3)Server佔用內存過大被內核Kill,或者被某些程序誤殺
複製代碼
可是根據當前環境,並不符合上述狀況,因此這個問題暫時尚未找到具體的緣由。bash
(1)首先看了下nginx的error.log,發現大量報錯:websocket
13247#0: *176909901 connect() failed (111: Connection refused) while connecting to upstream,
複製代碼
看了下nginx配置,能夠看出一開始的配置是很小的,因此對幾個配置進行增大swoole
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)還有在程序啓動會輸出:socket
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);
複製代碼
整理文檔的同時就是將解決問題的過程從新覆盤一遍,之後解決這種問題的思路就會比較清晰了。