[Nginx筆記]關於線上環境CLOSE_WAIT和TIME_WAIT過高


運維的同學和Team里面的一個同學分別遇到過Nginx在線上環境使用中會遇到TIME_WAIT過高或者CLOSE_WAIT過高的狀態

先從原因分析一下為什么,問題就迎刃而解了。

 

首先是TIME_WAIT:

  理解一下TIME_WAIT狀態產生的原因,這個問題已經被很多很多的書說爛了,但是為什么很多人還是不能解決,究其原因還是因為

大多數都是學術派,並沒有真正的遇到過這樣的問題,因為TIME_WAIT大量產生很多都發生在實際應用環境中。

TIME_WAIT產生的原因還是因為在通訊過程中服務端主動關閉造成的,在服務端發送了最后一個FIN包后,系統會等待 Double時間

MSL(Max Segment Lifetime)用於等待接受客戶端發送過來的FIN_ACK和FIN,這段時間服務端的對應的socket的fd是不能夠重新

利用的,這樣在大量的短連接服務中,會出現TIME_WAIT過多的現象。

解決方案:

  調整TIME_WAIT超時時間

  

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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM