運維的同窗和Team裏面的一個同窗分別遇到過Nginx在線上環境使用中會遇到TIME_WAIT太高或者CLOSE_WAIT太高的狀態node
先從緣由分析一下爲何,問題就迎刃而解了。算法
首先是TIME_WAIT:運維
理解一下TIME_WAIT狀態產生的緣由,這個問題已經被不少不少的書說爛了,可是爲何不少人仍是不能解決,究其緣由仍是由於socket
大多數都是學術派,並無真正的遇到過這樣的問題,由於TIME_WAIT大量產生不少都發生在實際應用環境中。tcp
TIME_WAIT產生的緣由仍是由於在通信過程當中服務端主動關閉形成的,在服務端發送了最後一個FIN包後,系統會等待 Double時間spa
的MSL(Max Segment Lifetime)用於等待接受客戶端發送過來的FIN_ACK和FIN,這段時間服務端的對應的socket的fd是不可以從新blog
利用的,這樣在大量的短鏈接服務中,會出現TIME_WAIT過多的現象。事件
解決方案:ip
調整TIME_WAIT超時時間class
vi /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,表示關閉。 net.ipv4.tcp_fin_timeout = 20
其次是CLOSE_WAIT:
CLOSE_WAIT產生的緣由是客戶端主動關閉,收到FIN包,應用層卻沒有作出關閉操做引發的。
CLOSE_WAIT在Nginx上面的產生緣由仍是由於Nagle's算法加Nginx自己EPOLL的ET觸發模式致使。
ET出發模式在數據就緒的時候會觸發一次回調操做,Nagle's算法會累積TCP包,若是最後的數據包和
FIN包被Nagle's算法合併,會致使EPOLL的ET模式只出發一次,然而在應用層的SOCKET是讀取返回
0才表明連接關閉,而讀取此次合併的數據包時是不返回0的,而後SOCKET之後都不會觸發事件,因此
致使應用層沒有關閉SOCKET,從而產生大量的CLOSE_WAIT狀態連接。
關閉TCP_NODELAY,在Nginx配置中加上
tcp_nodelay on;