網路優化之net.ipv4.tcp_tw_recycle引數

天府雲創發表於2018-02-05

本文為翻譯英文BLOG《Coping with the TCP TIME-WAIT state on busy Linux servers》,(http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html)但並非完整的翻譯,譯者CFC4N對原文理解後,進行了調整,增加了相關論點論據,跟原文稍有不同。翻譯的目的,是為了加深自己知識點的記憶,以及分享給其他朋友,或許對他們也有幫助。文章比較長,沒耐心請點關閉。


【案例分析1】

最近發現幾個監控用的指令碼在連線監控資料庫的時候偶爾會連不上,報錯:
 Couldn't connect to host:3306/tcp: IO::Socket::INET: connect: Cannot assign requested address
檢視了一下發現系統中存在大量處於TIME_WAIT狀態的tcp埠
$netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 50013
ESTABLISHED 27
SYN_RECV 1
由於要監控的主機太多,監控的agent可能在短時間內建立大量連線到監控資料庫(MySQL)並釋放造成的。在網上查閱了一些tcp引數的相關資料,最後通過修改了幾個系統核心的tcp引數緩解了該問題:
#vi /etc/sysctl.conf

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

#sysctl -p
其中:
net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連線,預設為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉。
修改完成並生效後,系統中處於TIME_WAIT狀態的tcp埠數量迅速下降到100左右:
$netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 82
ESTABLISHED 36
簡單記錄於此,備忘。


【案例分析2】

網上的帖子,大多都寫開啟net.ipv4.tcp_tw_recycle這個開關,可以快速回收處於TIME_WAIT狀態的socket(針對Server端而言)。

而實際上,這個開關,需要net.ipv4.tcp_timestamps(預設開啟的)這個開關開啟才有效果。
更不為提到卻很重要的一個資訊是:當tcp_tw_recycle開啟時(tcp_timestamps同時開啟,快速回收socket的效果達到),對於位於NAT裝置後面的Client來說,是一場災難——會導到NAT裝置後面的Client連線Server不穩定(有的Client能連線server,有的Client不能連線server)。也就是說,tcp_tw_recycle這個功能,是為“內部網路”(網路環境自己可控——不存在NAT的情況)設計的,對於公網,不宜使用。

通常,“回收”TIME_WAIT狀態的socket是因為“無法主動連線遠端”,因為無可用的埠,而不應該是要回收記憶體(沒有必要)。即,需求是“Client”的需求,Server會有“埠不夠用”的問題嗎?除非是前端機,需要大量的連線後端服務——即充當著Client的角色。
正確的解決這個總是辦法應該是:
net.ipv4.ip_local_port_range = 9000 6553 #預設值範圍較小
net.ipv4.tcp_max_tw_buckets = 10000 #預設值較小,還可適當調小
net.ipv4.tcp_tw_reuse = 1 #
net.ipv4.tcp_fin_timeout = 10 #

【案例分析3】

檢查net.ipv4.tcp_tw當前值,將當前的值更改為1分鐘:
[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
[root@aaa1 ~]#
vi /etc/sysctl

增加或修改net.ipv4.tcp_tw值:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

使核心引數生效:
[root@aaa1 ~]# sysctl -p

[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

設定這兩個引數: reuse是表示是否允許重新應用處於TIME-WAIT狀態的socket用於新的TCP連線; recyse是加速TIME-WAIT sockets回收

用netstat再觀察正常
這裡解決問題的關鍵是如何能夠重複利用time_wait的值,我們可以設定時檢查一下time和wait的值

#sysctl -a | grep time | grep wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

這樣的現象實際是正常的,有時和訪問量大有關,設定這兩個引數: reuse是表示是否允許重新應用處於TIME-WAIT狀態的socket用於新的TCP連線; recyse是加速TIME-WAIT sockets回收。

net.ipv4.tcp_syncookies=1 開啟TIME-WAIT套接字重用功能,對於存在大量連線的Web伺服器非常有效。
net.ipv4.tcp_tw_recyle=1
net.ipv4.tcp_tw_reuse=1 減少處於FIN-WAIT-2連線狀態的時間,使系統可以處理更多的連線。
net.ipv4.tcp_fin_timeout=30 減少TCP KeepAlive連線偵測的時間,使系統可以處理更多的連線。
net.ipv4.tcp_keepalive_time=1800 增加TCP SYN佇列長度,使系統可以處理更多的併發連線。
net.ipv4.tcp_max_syn_backlog=8192

net.ipv4.tcp_syncookies = 1
#表示開啟SYN Cookies。當出現SYN等待佇列溢位時,啟用cookies來處理,可防範少量SYN攻擊,預設為0,表示關閉;
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 = 30
#表示如果套接字由本端要求關閉,這個引數決定了它保持在FIN-WAIT-2狀態的時間。
net.ipv4.tcp_keepalive_time = 1200
#表示當keepalive起用的時候,TCP傳送keepalive訊息的頻度。預設是2小時,改為20分鐘。
net.ipv4.ip_local_port_range = 1024 65000
#表示用於向外連線的埠範圍。預設情況下很小:32768到61000,改為1024到65000。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,
#TIME_WAIT套接字將立刻被清除並列印警告資訊。預設為180000,改為5000。
#對於Apache、Nginx等伺服器,上幾行的引數可以很好地減少TIME_WAIT套接字數量,
#但是對於Squid,效果卻不大。此項引數可以控制TIME_WAIT套接字的最大數量,避免Squid伺服器被大量的TIME_WAIT套接字拖死
【案例分析4】

tcp_tw_recycle引數引發的故障 - http://blog.csdn.net/wireless_tech/article/details/6405755

【案例分析5】

tcp_tw_reuse、tcp_tw_recycle 使用場景及注意事項 - LittlePeng - https://www.cnblogs.com/lulu/p/4149312.html


不要啟用 net.ipv4.tcp_tw_recycle

linux 核心文件中,對net.ipv4.tcp_tw_recycle的描述並不是很明確。

tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)[譯者注:來自linux man tcp的描述]
Enable fast recycling of TIME-WAIT sockets. Enabling this option is not recommended since this causes
problems when working with NAT (Network Address Translation).
啟用TIME-WAIT狀態sockets的快速回收,這個選項不推薦啟用。在NAT(Network Address Translation)網路下,會導致大量的TCP連線建立錯誤。

與其功能相似的引數net.ipv4.tcp_tw_reuse,手冊裡稍微有點描述,如下:

tcp_tw_reuse (Boolean; default: disabled; since Linux 2.4.19/2.6)
Allow to reuse TIME-WAIT sockets for new connections when it is safe from protocol viewpoint. It
should not be changed without advice/request of technical experts.
//從協議設計上來看,對於TIME-WAIT狀態的sockets重用到新的TCP連線上來說,是安全的。(用於客戶端時的配置)

這裡的註釋說明非常的少,我們發現,網上很多linux引數調整指南都建議把這些引數net.ipv4.tcp_tw_recycle 設定1「啟用」,用於快速減少在TIME-WAIT狀態TCP連線數。

但是,在TCP(7)手冊中,引數net.ipv4.tcp_tw_recycle 非常蛋疼,尤其是在普通使用者家中,有多臺裝置,或者網咖、公司等多臺裝置,共用同一個NAT裝置環境下,TW回收選項是很有問題的面向公共伺服器作為它不會把手連線兩臺不同的計算機上,這問題很難發現,無從下手。

Enable fast recycling of TIME-WAIT sockets. Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation).
啟用TIME-WAIT狀態sockets的快速回收,這個選項不推薦啟用。在NAT(Network Address Translation)網路下,會導致大量的TCP連線建立錯誤。如果沒有技術大神的指點的話,千萬不要去改動他。

下文將給予更詳細的解釋,希望可以糾正網際網路上錯誤的觀點,尤其是轉載比較多的內容,搜尋時,往往排在前面,使用者往往接觸到的都是不嚴謹的或者是錯誤的知識點。

正如此文,在 net.ipv4.tcp_tw_recycle 控制引數中,儘管很多地方寫的是ipv4,但對ipv6同樣實用。此外,我們這裡聊的是Linux TCP協議棧,在linux上可能會受到Netfilter影響,稍微有差異。

關於TCP連線的TIME-WAIT狀態,它是為何而生,存在的意義是什麼?

讓我們回憶一下,什麼是TCP TIME-WAIT狀態?如下圖

這圖中的流程不是很好理解,再看一張流程更清晰的圖

TCP狀態流程圖


當TCP連線關閉之前,首先發起關閉的一方會進入TIME-WAIT狀態,另一方可以快速回收連線。
可以用ss -tan來檢視TCP 連線的當前狀態


TIME-WAIT狀態的作用

對於TIME-WAIT狀態來說,有兩個作用

一、人盡皆知的是,防止上一個TCP連線的延遲的資料包(發起關閉,但關閉沒完成),被接收後,影響到新的TCP連線。(唯一連線確認方式為四元組:源IP地址、目的IP地址、源埠、目的埠),包的序列號也有一定作用,會減少問題發生的機率,但無法完全避免。尤其是較大接收windows size的快速(回收)連線。RFC1137解釋了當TIME-WAIT狀態不足時將會發生什麼。如果TIME-WAIT狀態連線沒有被快速回收,會避免什麼問題呢?請看下面的例子:


縮短TIME-WAIT的時間後,延遲的TCP 包會被新建立的TCP連線接收。

二、另外一個作用是,當最後一個ACK丟失時,遠端連線進入LAST-ACK狀態,它可以確保遠端已經關閉當前TCP連線。如果沒有TIME-WAIT狀態,當遠端仍認為這個連線是有效的,則會繼續與其通訊,導致這個連線會被重新開啟。當遠端收到一個SYN 時,會回覆一個RST包,因為這SEQ不對,那麼新的連線將無法建立成功,報錯終止。


如果遠端因為最後一個ACK包丟失,導致停留在LAST-ACK狀態,將影響新建立具有相同四元組的TCP連線。

RFC 793中強調TIME-WAIT狀態必須是兩倍的MSL時間(max segment lifetime),在linux上,這個限制時間無法調整,寫死為1分鐘了,定義在include/net/tcp.h


曾有人提議將TCP TIME-WAIT時間改為一個可以自定義配置的引數,但被拒絕了,其實,這對TCP規範,對TIME-WAIT來說,是利大於弊的。

那麼問題來了

我們來看下,為什麼這個狀態能影響到一個處理大量連線的伺服器,從下面三個方面來說:

  • 新老連線(相同四元組)在TCP連線表中的slot複用避免

  • 核心中,socket結構體的記憶體佔用

  • 額外的CPU開銷

而ss -tan state time-wait|wc -l的結果,並不能說明這些問題。

Connection table slot連線表槽

處於TIME-WAIT狀態的TCP連線,在連結表槽中存活1分鐘,意味著另一個相同四元組(源地址,源埠,目標地址,目標埠)的連線不能出現,也就是說新的TCP(相同四元組)連線無法建立。

對於web伺服器來說,目標地址、目標埠都是固定值。如果web伺服器是在L7層的負載均衡後面,那麼源地址更是固定值。在LINUX上,作為客戶端時,客戶端埠預設可分配的數量是3W個(可以在引數net.ipv4.up_local_port_range上調整)。

這意味著,在web伺服器跟負載均衡伺服器之間,每分鐘只有3W個埠是處於established狀態,也就大約500連線每秒。

如果TIME-WAIT狀態的socket出現在客戶端,那這個問題很容易被發現。呼叫connect()函式會返回EADDRNOTAVAIL,程式也會記錄相關的錯誤到日誌。

如果TIME-WATI狀態的socket出現在服務端,問題會非常複雜,因為這裡並沒有日誌記錄,也沒有計數器參考。不過,可以列出伺服器上當前所有四元組連線的數量來確認


解決辦法是,增加四元組的範圍,這有很多方法去實現。(以下建議的順序,實施難度從小到大排列)

  • 修改net.ipv4.ip_local_port_range引數,增加客戶端埠可用範圍。

  • 增加服務端埠,多監聽一些埠,比如81、82、83這些,web伺服器前有負載均衡,對使用者友好。

  • 增加客戶端IP,尤其是作為負載均衡伺服器時,使用更多IP去跟後端的web伺服器通訊。

  • 增加服務端IP。

當然了,最後的辦法是調整net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle。但不到萬不得已,千萬別這麼做,稍後再講。


記憶體

保持大量的連線時,當多為每一連線多保留1分鐘,就會多消耗一些伺服器的記憶體。舉個栗子,如果伺服器每秒處理了1W個新的TCP連線,那麼伺服器將會存貨1W/s*60s = 60W個TIME-WAIT狀態的TCP連線,那這將會佔用多大的記憶體麼?別擔心,少年,沒那麼多。

首先,從應用的角度來看,一個TIME-WAIT狀態的socket不會消耗任何記憶體:socket已經關了。在核心中,TIME-WAIT狀態的socket,對於三種不同的作用,有三個不同的結構。

一、“TCP established hash table”的連線儲存雜湊表(包括其他非established狀態的連線),當有新的資料包發來時,是用來定位查詢存活狀態的連線的。
該雜湊表的bucket都包括在TIME-WAIT連線列表以及正在活躍的連線列表中(netstat -antp命令的結果中,沒PID的TIME_WAIT狀態連線,跟有PID的活躍連線兩種)。

該雜湊表的大小,取決於作業系統記憶體大小。在系統引導時,會列印出來,dmesg日誌中可以看到。


這個數值,有可能被kernel啟動引數thash_entries(設定TCP連線雜湊表的最大數目)的改動而將其覆蓋。

在TIME-WAIT狀態連線列表中,每一個元素都是一個tcp_timewait_sock結構體,其他狀態的連線都是tcp_sock結構體。


二、有一組叫做“death row”的連線列表,是用來終止TIME-WAIT狀態的連線的,這會在他們過期之前,開始申請。它佔用的記憶體空間,跟在連線雜湊表中的一樣。這個結構體hlist_node tw_death_node是inet_timewait_sock的一個成員,如上程式碼的倒數第二行。

三、有個繫結埠的雜湊表,儲存繫結埠跟其他引數,用來確保當前埠沒有被使用的,比如在listen監聽時的指定埠,或者連線其他socket時,系統動態分配的埠。該雜湊表的大小跟連線雜湊表大小一樣。


每個元素都是inet_bind_socket結構體。每個繫結的埠都會有一個元素。對於web伺服器來說,它繫結的是80埠,其TIME-WAIT連線都是共享同一個entry的。另外,連線到遠端伺服器的本地連線,他們的埠都是隨機分配的,並不共享其entry。

所以,我們只關心結構體tcp_timewait_sock跟結構體inet_bind_socket所佔用的空間大小。每一個連到遠端,或遠端連到本地的一個TIME-WAIT狀態的連線,都有一個tcp_timewait_sock結構體。還有個結構體inet_bind_socket,只會在連到遠端的連線會存在,遠端連過來的連線沒這個結構體。

tcp_timewait_sock結構體的大小隻有168 bytes,inet_bind_socket結構體為48bytes:


所以,當伺服器上有4W個連進來的連線進入TIME-WAIT狀態時,才用了10MB不到的記憶體。如果伺服器上有4W個連線到遠端的連線進入TIME-WAIT狀態時,才用了2.5MB的記憶體。再來看下slabtop的結果,這裡測試資料是5W個TIME-WAIT狀態的連線結果,其中4.5W是連線到遠端的連線:


命令執行結果原樣輸出,一個字元都沒動。TIME-WAIT狀態的連線佔用記憶體非常的小。如果你的伺服器上要處理每秒成千上萬的新建TCP連線,你可能需要多一點的記憶體才能 正確無誤的跟客戶端做資料通訊。但TIME-WAIT狀態連線的記憶體佔用,簡直可以無視。

CPU

在CPU這邊,查詢一個空閒埠的操作,還是蠻珍貴的。這由inet_csk_get_port() 函式,加鎖,遍歷整個空閒埠列表實現。這個雜湊表裡條目數量大通常不是問題,如果伺服器上存在大量連線到遠端TIME-WAIT狀態的連線(比如FPM連redis、memcache之類),都會同享相同的profile,這個特性會非常快的按照順序找到一個新的空閒埠。

其他解決辦法

如果你讀了上面的章節後,仍對TIME-WAIT狀態的連線存有疑問,那麼接著看吧:

  • 禁用socket延遲關閉「譯者注1:以ubuntu 12.04為例,linger結構體定義在:/usr/src/linux-headers-3.2.0-23/include/linux/socket.h」

  • 禁用net.ipv4.tcp_tw_reuse

  • 禁用net.ipv4.tcp_tw_recycle


當close被呼叫時,SOCKET需要延遲關閉(lingering),在核心buffers中的殘留資料將會傳送到遠端地址,同時,socket會切換到TIME-WAIT狀態。如果禁用此選項,則呼叫close之後,底層也會關閉,不會將Buffers中殘留資料未傳送的資料繼續傳送。

不過呢,應用程式可以選擇禁用socket lingering延遲關閉行為。關於socket lingering 延遲關閉,下面兩個行為簡單描述一下:
第一種情況,close函式後,並不會直接終止該四元組連線序號,而是在buffers任何殘留資料都會被丟棄。該TCP連線將會收到一個RST的關閉訊號,之後,服務端將立刻銷燬該(四元組)連線。 在這種做法中,不會再有TIME-WAIT狀態的SOCKET出現。第二種情況,如果當呼叫close函式後,socket傳送buffer中仍然有殘留資料,此程式將會休眠,直到所有資料都傳送完成並確認,或者所配置的linger計時器過期了。非阻塞socket可以設定不休眠。如上,這些過程都都在底層發生,這個機制確保殘留資料在配置的超時時間內都傳送出去。 如果資料正常傳送出去,close包也正常傳送,那麼將會轉換為TIME-WAIT狀態。其他異常情況下,客戶端將會收到RST的連線關閉訊號,同時,服務端殘留資料會被丟棄。

這裡的兩種情況,禁用socket linger延遲關閉不是萬金油。但在HAproxy,Nginx(反代)場景中,在TCP協議上層的應用上(比如HTTP),比較合適。同樣,也有很多無可厚非的理由不能禁用它。

net.ipv4.tcp_tw_reuse

TIME-WAIT狀態是為了防止不相關的延遲請求包被接受。但在某些特定條件下,很有可能出現,新建立的TCP連線請求包,被老連線(同樣的四元組,暫時還是TIME-WAIT狀態,回收中)的連線誤處理。RFC 1323 實現了TCP擴充規範,以保證網路繁忙狀態下的高可用。除此之外,另外,它定義了一個新的TCP選項–兩個四位元組的timestamp fields時間戳欄位,第一個是TCP傳送方的當前時鐘時間戳,而第二個是從遠端主機接收到的最新時間戳。

啟用net.ipv4.tcp_tw_reuse後,如果新的時間戳,比以前儲存的時間戳更大,那麼linux將會從TIME-WAIT狀態的存活連線中,選取一個,重新分配給新的連線出去的TCP連線。

連出的TIME-WAIT狀態連線,僅僅1秒後就可以被重用了。

如何確通訊安全性?

TIME-WAIT的第一個作用是避免新的連線(不相關的)接收到重複的資料包。由於使用了時間戳,重複的資料包會因為timestamp過期而丟棄。
第二個作用是確保遠端端(遠端的不一定是服務端,有可能,對於伺服器來說,遠端的是客戶端,我這裡就用遠端端來代替)是不是在LAST-ACK狀態。因為有可能丟ACK包丟。遠端端會重發FIN包,直到

  • 放棄(連線斷開)

  • 等到ACK包

  • 收到RST包

如果 FIN包接及時收到,本地端依然是TIME-WAIT狀態,同時,ACK包也會傳送出去。

一旦新的連線替換了TIME-WAIT的entry,新連線的SYN包會被忽略掉(這得感謝timestramps),也不會應答RST包,但會重傳FIN包。 FIN包將會收到一個RST包的應答(因為本地連線是SYN-SENT狀態),這會讓遠端端跳過LAST-ACK狀態。 最初的SYN包將會在1秒後重新傳送,然後完成連線的建立。看起來沒有啥錯誤發生,只是延遲了一下。


另外,當連線被重用時,TWrecycled計數器會增加的。「譯者注:見/proc/net/netstat 中TWrecycled的值」

net.ipv4.tcp_tw_recycle

這種機制也依賴時間戳選項,這也會影響到所有連線進來和連線出去的連線。「譯者注:linux上tcp_timestamps預設開啟」
TIME-WAIT狀態計劃更早的過期:它將會在超時重發(RTO)間隔後移除(底層會根據當前連線的延遲狀況根據RTT來計算RTO值,上篇《PHP-FPM中backlog引數變更的一些思考》也有提到過,比較複雜的演算法)。可以執行ss指令,獲取當前存活的TCP連線狀態,檢視這些資料。「譯者注:linux指令ss的結果中rto,rtt值單位均為ms」


Linux將會放棄所有來自遠端端的timestramp時間戳小於上次記錄的時間戳(也是遠端端發來的)的任何資料包。除非TIME-WAIT狀態已經過期。


當遠端端主機HOST處於NAT網路中時,時間戳在一分鐘之內(MSL時間間隔)將禁止了NAT網路後面,除了這臺主機以外的其他任何主機連線,因為他們都有各自CPU CLOCK,各自的時間戳。這會導致很多疑難雜症,很難去排查,建議你禁用這個選項。另外,對方上TCP的LAST-ACK狀態是體現本機net.ipv4.tcp_tw_recycle的最好資料。

總結

最合適的解決方案是增加更多的四元組數目,比如,伺服器可用埠,或伺服器IP,讓伺服器能容納足夠多的TIME-WAIT狀態連線。在我們常見的網際網路架構中(NGINX反代跟NGINX,NGINX跟FPM,FPM跟redis、mysql、memcache等),減少TIME-WAIT狀態的TCP連線,最有效的是使用長連線,不要用短連線,尤其是負載均衡跟web伺服器之間。尤其是鏈家事件中的PHP連不上redis


在服務端,不要啟用net.ipv4.tcp_tw_recycle,除非你能確保你的伺服器網路環境不是NAT。在服務端上啟用net.ipv4.tw_reuse對於連線進來的TCP連線來說,並沒有任何卵用。


在客戶端(尤其是伺服器上,某服務以客戶端形式執行時,比如上面提到的nginx反代,連線著redis、mysql的FPM等等)上啟用net.ipv4.tcp_tw_reuse,還算稍微安全的解決TIME-WAIT的方案。再開啟net.ipv4.tcp_tw_recycle的話,對客戶端(或以客戶端形式)的回收,也沒有什麼卵用,反而會發生很多詭異的事情(尤其是FPM這種伺服器上,相對nginx是服務端,相對redis是客戶端)。


這個就矛盾了。該不該設定呢?


我認為這樣:

1. 如果是服務企業客戶,或者是一個企業網際網路就用,那就設定為0,企業客戶投訴和抱怨影響是非常大的,只能其它方面來優化。

2. 如果是一個網際網路普通使用者使用的網站,設定為1,那也影響不大。



最後引用一下W. Richard Stevens在《UNIX網路程式設計》的一句話

The TIME_WAIT state is our friend and is there to help us (i.e., to let old duplicate segments expire in the network). Instead of trying to avoid the state, we should understand it.
譯者:存在即合理,勇敢面對,而不是逃避。


譯者注:

  • 譯者根據原文做了翻譯,並增加了相關論點論據,跟原文稍有不同。

  • linux的netstat命令ss命令的結果中,前者是TIME_WAIT之類,分個字元是下劃線,而後者是TIME-WAIT的中劃線。

殘酷的案例:

  • Clients behind NAT/Stateful FW will get dropped, 99.99999999% of time should never be enabledTuning TCP and nginx on ec2中30頁內容

參考資料:

相關文章