解決MySQL建立連接問題,快速回收復用TCP的TIME_WAIT


最近同事遇到一個問題,使用python開發的工具在執行的時候無法和MySQL建立連接,其最直接的現象就是滿篇的TIME_WAIT,最后通過調整tcp_timestamps參數問題得以解決,再次記錄一下這次解決的經驗總結。

ps:不過先汗顏一個,對基礎的tcp知識太不敏感了,需要回爐重新學習啊。

 

一、看下TIME_WAIT產生的原因

大家都知道建立連接是著名的三次握手機制。

那么如何關閉連接呢? 其實也是著名的四次握手機制。

 

TIME_WAIT就產生在四次握手的的主動關閉方,而server端會進入close狀態。

那么TIME_WAIT什么時候會消失呢?LINUX會在2MSL時間內消失。(MSL是最大分段生存期,默認為2分鍾)

 

二、無法建立連接的原因

  由於同事的腳本的用途是進行采集數據后的寫入操作,為了加快速度故使用python的map功能並發寫入數據庫,當在腳本執行的服務器上報錯后,發現滿篇都是TIME_WAIT的現象。

  經過我們內部討論,初步認為是由於TIME_WAT沒有快速回收導致Linux的可用端口被沾滿導致無發建立連接,和MySQL的設置沒有關系。

  查看目前Linux可用端口范圍:

[me]sysctl -a|grep ip_local_port_range 
net.ipv4.ip_local_port_range = 32768    61000

  查看當前占用的端口直接用netstat就可以了:

netstat -nat|grep -i time_wait|wc -l

 

三、如何解決?

對於TCP鏈接的優化大家都知道的三個參數:tcp_tw_reuse、tcp_tw_recycle、tcp_timestamp

1、我們先看看這3個參數的定義和作用。

tcp_tw_reuse:用來使用time-wait狀態的sockets重用

Allow to reuse TIME-WAIT sockets for new connections when it is
safe from protocol viewpoint. Default value is 0. It should not be changed without advice/request of technical experts.

tcp_tw_recycle:用來加速對time-wait

Enable fast recycling TIME-WAIT sockets. Default value is 0.
It should not be changed without advice/request of technical experts.

tcp_timestamp:在TCP的包頭添加時間戳

Enable timestamps as defined in RFC1323

 

2、調整記錄

我們先查看服務器的狀態,發現reuse和recycle的參數都是1,但是time_wait並沒有被很快的回收,也沒有被快速的重用。

[root ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse 
1
[root ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle 
1

后來發現是由於tcp_timestamp這個參數設置為0的原因

[root ~] cat /proc/sys/net/ipv4/tcp_timestamps 
0

將這個參數置為1之后,time_wati的狀態立刻下降了很多,腳本也可以正常執行了。看來tcp_timestamp非常關鍵。

 

3、探尋原因

但是,究竟是tcp_tw_reuse起作用了? 還是tcp_tw_recycle起作用了?我們還是不知道,只能從現象得知問題解決了。

我們將tcp_tw_recycle的值設定為0之后,再次測試,再次出現了大量的time_wait現象。

為了證明tcp_tw_recycle真正起作用了,我們再次將tcp_tw_reuse參數設置為1,這時候也再次出現了大量的time_wait的現象。

看來,最終我們的結論是同時開啟tcp_tw_recycle,tcp_tw_reuse和tcp_timestamp才能真正做到快速回收和服用time-wait狀態的socket。

從stackoverflow上看到的一個答案比較靠譜。點這里

但是同時也發現,網上有很多信息顯示,如果同時開啟tcp_tw_recycle和tcp_timestamp會出現問題。主要是由於TCP的一種行為

RFC 1323  TCP Extensions for High Performance  Jacobson, Braden, & Borman
An additional mechanism could be added to the TCP, a per-host
cache of the last timestamp received from any connection.
This value could then be used in the PAWS mechanism to reject
old duplicate segments from earlier incarnations of the
connection, if the timestamp clock can be guaranteed to have
ticked at least once since the old connection was open.  This
would require that the TIME-WAIT delay plus the RTT together
must be at least one tick of the sender's timestamp clock.
Such an extension is not part of the proposal of this RFC.

 

三、結論

1、開啟tcp_timestamp是開啟tcp_tw_recycle,tcp_tw_reuse和tcp_timestamp的前提條件。

2、但是在nat模式下,不用將tcp_tw_recycle和tcp_timestamp同時開啟,這會造成tcp超時引發故障。

 

附錄:

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

http://lxr.free-electrons.com/source/net/ipv4/tcp_minisocks.c#L92

http://www.ietf.org/rfc/rfc1323.txt

 

 

 


免責聲明!

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



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