Manjusaka

Manjusaka

Supervisor 的一個隱藏坑

本垃圾 API 搬運工程師又來了啊,= = 今天因為 Supervisor 一個隱藏的參數配置,造成了一個重要項目的線上崩潰。= = 我覺得還是有必要分享一波,所以寫了一篇垃圾水文。

起因#

寫著寫著代碼,突然接到一堆報警郵件,讓我直接覺得世界不那麼可愛

然後定睛一看異常信息?臥槽?新建連接就馬上傳說中的 [Errno 24] Too many open files ??這搞你 xxx 啊,開始搞呗。

查 bug#

首先,眾所周知,Linux 中萬物皆文件 = =,於是我們操作網絡連接的過程,其實也就是操作 File Descriptor 的問題 = =,誒,既然 Too many open files 那就優先考慮,是不是系統設置的閥值太小了,於是 ulimit -a 一把梭??

誒?open files 一欄數字不小啊?足夠啊?那這特麼是什麼鬼啊?

行吧,查一下網絡連接吧, 一把梭,netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 統計下,當時處於各個狀態的連接數量吧

誒?有點意思,TIME_WAIT 數量太多了吧?誒?有意思,那就祭出老夫的內核網絡參數的半吊子功夫,魔改一下呗?

#參數優化
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
net.ipv4.tcp_fin_timeout = 30
#表示當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改為300秒,
net.ipv4.tcp_keepalive_time = 300
#表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉
net.ipv4.tcp_syncookies = 1
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
net.ipv4.tcp_tw_reuse = 1
#表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉,當前TIME-WAIT 過多,所以開啟快速回收
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000

/etc/sysctl.conf 中新增如上一些配置項。然後 sysctl -p 生效一波。開始看效果吧

誒!報錯數量是在減小,TIME_WAIT 數量也逐漸正常

誒???等等???其餘機器沒 TIME_WAIT 過多的問題啊,那這尼瑪是什麼鬼?而且快速回收 TIME_WAIT 的連接也會帶來其餘的副作用(後面單章說)

= = 好吧,現在懷疑,是不是 Supervisor 的問題,好的,文檔翻閱大賽,開始

恩,,翻了半天,查到原因了,跟一個叫做 minfds 的參數相關

描述如下

The minimum number of file descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minfds. The hard limit may only be raised if supervisord is run as root. supervisord uses file descriptors liberally, and will enter a failure mode when one cannot be obtained from the OS, so it’s useful to be able to specify a minimum value to ensure it doesn’t run out of them during execution. These limits will be inherited by the managed subprocesses. This option is particularly useful on Solaris, which has a low per-process fd limit by default.

大意為,Supervisor 啟動時,將根據 minfds 的值來確定系統中是否有足夠的空餘 fd 供其使用。同時因為我們跑在 Supervisor 中的服務,都是由 Supervisord fork 而來,因為父子關係,同時保證安全,單個進程開啟的描述符最多不允許超過 minfds 設置的值,默認為 1024。然後,它補了一把刀,如果你用 root 用戶運行的話,我們默認給你搞到系統最大的哦!

臥槽。。。原來是這啊,你誰沒事用 root 跑服務啊 = = 簡直藥丸。。。

行吧,改參數,改參數

後續#

最後這事就這樣的結束了,趟一個雷,順便複習了下內核的網絡參數,雖然感覺美滋滋,不過感覺,貴 Supervisor 吃枣藥丸!

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。