公司羣裏,運維發現一個問題,task服務報錯(以下)python
The stream or file \"/data/logs/adn_task/offer_service.log\" could not be opened: failed to open stream: Too many open files
測試老大看到了,根據經驗就推測是應該是文件句柄使用完了,應該有TCP鏈接不少沒釋放,果然發現是不少CLOSE_WAIT的狀態linux
短連接,一次連接就會佔用一個端口,一個端口就是一個文件描述符;
文件描述符 又稱 句柄,linux系統最大的句柄數是65535,能夠經過ulimit -a 查看redis
TCP創建鏈接須要通過三次握手;
通俗版本:
A: 你好,你能聽見我說話嗎?
B: 能聽到,你能聽到我說話嗎?
A:我也能聽到,咱們開始通訊吧shell
專業版本:
創建TCP鏈接時,須要客戶端和服務器共發送3個包。服務器
TCP鏈接斷開須要通過四次揮手;
通俗版本:
前提A和B在通話
A:好的,個人話就說完了(FIN);
B:哦哦,我知道你說完啦(ACK),我還有說兩句哈;A: (沒說話,一直聽着)
B:哦了,我也說完了(FIN)
A:好的,我也知道你說玩了(ACK),掛電話吧網絡
專業版本:運維
linux上起了一個redis服務
本地起的6379端口tcp
仍是同一臺機器上,經過python腳本鏈接該redis服務:測試
此時網絡鏈接以下:
關注這兩個網絡鏈接,第一個是redis-server的,第二是python腳本的,此時都是ESTABLISHED狀態,表示這兩個進程創建了鏈接優化
如今斷掉python
以前的python的那個鏈接,是TIME_WAIT狀態
客戶端(主動方)主動斷開,進入TIME_WAIT狀態,服務端(被動方)進去CLOSE狀態,就是沒有顯示了
等待2MSL(1分鐘)後,以下:
TIME_WAIT狀態的鏈接也消失了,TIME_WAIT回收機制,系統ing過一段時間會回收,資源重利用
先創建鏈接,以下:
關掉redis服務,service redis stop
以前的redis-server的45370端口鏈接 進入了FIN_WAIT2狀態,而python端(被動關閉方)就進去了CLOSE_WAIT狀態
等待30s後,在看鏈接
只有python的那條CLOSE_WAIT了
再次操做python端的腳本,再次get
關於6379端口(redis端口)的網絡鏈接都沒有了
如何快速回收TIME_WAIT和FIN_WAIT
/etc/sysctl.conf 包含如下配置項
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
root權限 執行/sbin/sysctl -p使之生效
我的經驗,不必定對,若有錯誤,請指正