【轉】打開linux-tcp端口快速回收


 

原文:http://www.zhaoxiaodan.com/lnmp/%E6%89%93%E5%BC%80linux-tcp%E7%AB%AF%E5%8F%A3%E5%BF%AB%E9%80%9F%E5%9B%9E%E6%94%B6.html

-------------------------------------------------------------------------------------------------------

打開linux-tcp端口快速回收

事件:

之前看到一些文章說關於流量升高導致TIME_WAIT增加,MySQL連接大量失敗的問題, 當時並不是很理解究竟怎么回事

今天在對阿里雲服務器上的tengine 做 1000個並發的webbench 測試時,ssh 會被踢掉,

懷疑網絡鏈接的問題 ,用netstat 查看 ,看到有很多很多 TIME_WAIT 狀態的 tcp 鏈接:

…
tcp 0 0 42.121.16.232:www 42.121.16.220:44091 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:42309 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:43896 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:44150 TIME_WAIT
tcp 0 0 localhost:9000 localhost:34634 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:44493 TIME_WAIT
tcp 0 0 localhost:9000 localhost:35354 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:42770 TIME_WAIT
tcp 0 0 localhost:9000 localhost:34995 TIME_WAIT
tcp 0 0 localhost:9000 localhost:35038 TIME_WAIT
tcp 0 0 localhost:9000 localhost:34108 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:41764 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:42337 TIME_WAIT
tcp 0 0 42.121.16.232:www 42.121.16.220:44179 TIME_WAIT
…

nginx將php解析通過TCP轉發給php-fpm,需要占用一個TCP,php-fpm中的mysql連接, 又需要占用一個TCP

(但是檢查發現, 其實沒有 php-fpm -> mysql 的鏈接, 因為mysql使用的不是TCP而是UNIX SOCKET, 具體看 這里 )

再看:

~# netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
SYN_RECV 186
TIME_WAIT 30245
ESTABLISHED 211
FIN_WAIT1 333

TIME_WAIT 居然有3W多個 ,隨着時間推移還會極速增加中

怪不得了, 端口也就65536個, 用完了自然就沒了!!

而且,

解決辦法:打開LINUX TCP 端口快速回收

修改 /etc/sysctl.conf, 添加兩條數據

#打開重用
net.ipv4.tcp_tw_reuse = 1
#打開快速回收
net.ipv4.tcp_tw_recycle = 1

保存后執行 sysctl -p 生效

注:

如果nginx,php-fpm,mysql都在同一台機器, 推薦php-fpm和mysql都使用UNIX SOKCET. 方法看 這里

TIME_WAIT產生原因:

1、nginx現有的負載均衡模塊實現php fastcgi負載均衡,nginx使用了短連接方式,所以會造成大量處於TIME_WAIT狀態的連接。

2、TCP/IP設計者本來是這么設計的, 主要有兩個原因

(1) 防止上一次連接中的包,迷路后重新出現,影響新連接(經過2MSL,上一次連接中所有的重復包都會消失)

(2) 可靠的關閉TCP連接, 在主動關閉方發送的最后一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。

為什么短連接TCP在高並發大流量會扛不住?

一般LNMP服務器架構, 都是nginx接受http請求, 然后將php文件的解析轉發給php-fpm, 這個過程nginx需要使用新的TCP端口與php-fpm的9000端口去建立TCP鏈接, 那么, 一個php請求就需要一個新的端口

若2MSL時間為1分鍾以上,同時,不同用戶http兩次請求間隔很短。那么反代的端口,5秒用1W個,10秒2W,15秒3W,20秒4W,25秒5W,30秒6W!!!而linux最大端口就是65535個, 前面已經用掉的端口還沒被回收掉。那么將會有很多的用戶請求被nginx接收之后,因沒有端口資源而無法與php-fpm創建tcp連接… 所以服務器會’掛掉’


免責聲明!

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



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