tcp_timestamps和tcp_tw_recycle

 

不一樣時開啓tcp_timestamps和tcp_tw_recycle的場景描述html

FULL NAT下web

FULL NAT  在client請求VIP 時,不只替換了package 的dst ip,還替換了package的 src ip;但VIP 返回給client時也替換了src ip數據庫

lvs後端爲web服務器。後端

假如web服務器開啓了tcp的tcp_timestamps和tcp_tw_recycle這兩個參數。那麼存在下面這種狀況緩存

 

RFC1323中有以下一段描述:bash

An additional mechanism could be added to the TCP, a per-hostcache of the last timestamp received from any connection.This value could then be used in the PAWS mechanism to rejectold duplicate segments from earlier incarnations of theconnection, if the timestamp clock can be guaranteed to haveticked at least once since the old connection was open. Thiswould require that the TIME-WAIT delay plus the RTT togethermust be at least one tick of the sender’s timestamp clock.Such an extension is not part of the proposal of this RFC.服務器

大概意思是說TCP有一種行爲,能夠緩存每一個鏈接最新的時間戳,後續請求中若是時間戳小於緩存的時間戳,即視爲無效,相應的數據包會被丟棄。意思就是同一個源IP來鏈接同一個目的端口的數據包時間戳必須是遞增的網絡

Linux是否啓用這種行爲取決於tcp_timestamps和tcp_tw_recycle,由於tcp_timestamps缺省就是開啓的,因此當tcp_tw_recycle被開啓後,實際上這種行爲就被激活了。負載均衡

如今不少公司都用LVS作負載均衡,一般是前面一臺LVS,後面多臺後端服務器,這其實就是NAT,當請求到達LVS後,它修改地址數據後便轉發給後端服務器,
但不會修改時間戳數據,對於後端服務器來講,請求的源地址就是LVS的地址,加上web端口會複用,因此從後端服務器的角度看,本來不一樣客戶端的請求通過LVS的轉發,
就可能會被認爲是同一個鏈接,加之不一樣客戶端的時間可能不一致,因此就會出現時間戳錯亂的現象,因而後面的數據包就被丟棄了,
具體的表現一般是是客戶端明明發送的SYN,但服務端就是不響應ACK,還能夠經過下面命令來確認數據包不斷被丟棄的現象socket

假如LVS地址是222.222.222.222,名字是L

web服務器地址爲111.111.111.111,名字是W

好比客戶端地址客戶端C1地址爲100.100.100.101,客戶端C2地址爲100.100.100.102

假如出現這種狀況

13:23:02這個時間點

C1發出的TCP數據包源IP和源端口爲100.100.100.101:6332,目標地址和端口是222.222.222.222:80

13:23:05這個時間點

C2發出的TCP數據包源IP和源端口爲100.100.100.102:52223,目標地址和端口是222.222.222.222:80

 

通過LVS的full nat。

假如在13:23:06時刻LVS收到C2的數據包

C2的數據包被轉換爲

222.222.222.222:52223 ---->111.111.111.111:80

假如在13:23:07時刻LVS收到C1的數據包

C1的數據包被轉換爲

222.222.222.222:6332 ---->111.111.111.111:80

假如web服務器開啓了tcp的tcp_timestamps和tcp_tw_recycle這兩個參數。web服務器根據數據包的時間戳

C1的數據包因爲時間戳小於目前系統登記的此源IP鏈接的時間戳,被認爲是重傳數據,C1的數據包就被丟棄了

 (不只lvs的full nat會出現源地址被替換的狀況,一些3層交換機做爲負載均衡也會把源地址替換掉)

這個參數默認2.4的內核就禁用了。咱們是能不開啓就不要開啓

 

 注意點

1. tw_reuse,tw_recycle 必須在客戶端和服務端timestamps 開啓時才管用(默認打開),其實意思就是假如服務端和客戶端兩邊有一邊timestamps沒開啓。tw_reuse和tw_recycle都沒啥做用
2. tw_reuse 只對客戶端起做用,開啓後客戶端在1s內回收。reuse就是重用time_wait的socket鏈接。 服務端同一個端口被鏈接理論上是沒限制的。
3. tw_recycle 對客戶端和服務器同時起做用,開啓後在 3.5*RTO 內回收,RTO 200ms~ 120s 具體時間視網絡情況。
  內網情況比tw_reuse 稍快,公網尤爲移動網絡大多要比tw_reuse 慢,優勢就是可以回收服務端的TIME_WAIT數量

 

 

對於客戶端
1. 做爲客戶端由於有端口65535問題,TIME_OUT過多直接影響處理能力,打開tw_reuse 便可解決,不建議同時打開tw_recycle,幫助不大。
2. tw_reuse 幫助客戶端1s完成鏈接回收,基本可實現單機6w/s請求,須要再高就增長IP數量吧。
3. 若是內網壓測場景,且客戶端不須要接收鏈接,同時tw_recycle 會有一點點好處。

 

 

對於服務端
1. 打開tw_reuse無效,由於是客戶端鏈接web服務器,服務端確定不會重用socket去主動鏈接客戶端。這個參數服務器通常用不到,除非web服務器又做爲客戶端去鏈接後端數據庫纔用到。

可是web服務器做爲客戶端鏈接數據庫達到6萬端口的限制時你的數據庫早承受不了壓力癱瘓了。通常數據庫5000鏈接數就已經很高了。

tw_resue這個參數,只有客戶端用獲得。意思就是重用處於time_wait的socket鏈接。


2. 線上環境 tw_recycle 不要打開
服務器處於NAT 負載後,或者客戶端處於NAT後(這是必定的事情,基本公司家庭網絡都走NAT);
公網服務打開就可能形成部分鏈接失敗,內網的話到時能夠視狀況打開;
有些負載均衡設備會把timestamp 都給清空,後端web服務器開啓不開啓tw_recycle都無所謂了。


3. 服務器TIME_WAIT 高怎麼辦

服務器time_wait不用擔憂,由於我是服務端,是客戶端不少IP和端口主動鏈接個人一個端口,好比鏈接個人80端口。極可能出現一種狀況就是雖然我機器上有10萬個time_wait鏈接。可是個人端口才用到一個80端口。

不像客戶端有端口限制,處理大量TIME_WAIT Linux已經優化很好了,每一個處於TIME_WAIT 狀態下鏈接內存消耗不多,
並且也能經過tcp_max_tw_buckets = 262144 配置最大上限,現代機器通常也不缺這點內存。

 

 

 總之,生產中,服務器無論有沒有在nat設備後面.

tcp_tw_recycle不開啓就好了。默認就是不開啓的狀態,值爲0

tcp_timestamps保持默認開啓就好了,值爲1

tcp_tw_reuse.客戶端最好開啓。負載均衡設備鏈接web服務器時,輔助均衡設備也儘可能開啓

 

關於服務器端出現大量time_wait,有些人會問,我是web服務器端,爲何會出現客戶端那種time_wait。

其實關於time_wait,它是出如今主動請求關閉鏈接的那一段。 服務器主動關閉http的鏈接。它就轉變爲了客戶端。

發起斷開鏈接這個動做,不是說就必定是客戶端發起斷開的。不少時候都是服務器端先發起斷開鏈接操做。好比不少http服務器,短鏈接。不少時候服務器主動斷開。

 

服務出現tcp鏈接問題能夠先查看下下面,看看是否有不少,不少時候就是開啓了tcp_tw_recycle致使的

[game@localhost ~]$ netstat -s | grep timestamp
    351 packets rejects in established connections because of timestamp
[game@localhost ~]$ 

  

客戶端相關優化的地方以下。(服務器不開啓tcp_tw_recycle便可)

[root@B ~]# cat /proc/sys/net/ipv4/ip_local_port_range 
32768	61000
[root@B ~]# cat /proc/sys/net/ipv4/tcp_timestamps 
1
[root@B ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle 
0
[root@B ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse 
0
[root@B ~]# echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
[root@B ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse 
1
[root@B ~]# echo "10240  62000" > /proc/sys/net/ipv4/ip_local_port_range
[root@B ~]# cat /proc/sys/net/ipv4/ip_local_port_range 
10240	62000
[root@B ~]# 

  

 

 

 

相關參考連接

http://blog.csdn.net/caianye/article/details/38540867

http://elf8848.iteye.com/blog/2089414

http://blog.sina.com.cn/s/blog_781b0c850100znjd.html

http://blog.csdn.net/yunhua_lee/article/details/8146845

http://blog.sina.com.cn/s/blog_781b0c850100znjd.html

 http://www.cnblogs.com/lulu/p/4149312.html

相關文章
相關標籤/搜索