记一次TCP连接异常故障解决
為什么80%的碼農都做不了架構師?>>> ??
一.情況表現為
? ? 1.在公司內網對站點的http訪問:
? ? ? ? linux主機出現故障:curl以及抓包分析,發現服務端不響應linux客戶端的請求,無法建立TCP連接,瀏覽器返回“無法連接到服務器”
? ? ? ? windows主機正常
? ? 2.http訪問質量下降:
? ? ? ? 基調顯示,新架構上線后,訪問質量下滑,主要表現為
? ? ? ? 2.1.訪問提示“無法連接到服務器”
? ? ? ? 2.2.僅少數人遇到這種故障,并且一天中不是每次訪問都會遇到,而是出現時好時壞的現象
二.處理過程
? ? 直接上google搜索關鍵字“服務器無法建立TCP連接”。
? ? 翻了幾頁后,發現這篇博文:“http://www.sunchis.com/html/os/linux/2012/0518/413.html”。
? ? 看了一下,和我們公司內網的表現一模一樣,但各種問題(1為這方面基礎知識薄弱,2為沒有時間驗證此配置)
? ? 然后這種問題持續了n久…一直以為是內部設備問題
? ? 后期搞不定了,大膽在線上啟用這個參數“net.ipv4.tcp_timestamps = 0”,做了下測試后,發現故障解除,原故障機每次訪問都正常了!
? ? 不過還是不明其中原理,只是大意了解,同樣處于NAT上網方式的用戶里(與別人共用出口IP地址),如果你的時間戳小于別人的,那么服務器不會響應你的TCP請求,要忽略此項,將net.ipv4.tcp_timestamps = 0(/etc/sysctl.conf)
三.總結
? ? 后期學習時,看見了一個更加詳細的博客,講的很詳細,也引入了新的問題:http://huoding.com/2012/01/19/142
? ? ====== 小抄 ======
? ? 其實,linux服務器原本對時間戳(timestamps)默認是不開啟的,Linux是否啟用這種行為取決于tcp_timestamps和tcp_tw_recycle,因為tcp_timestamps缺省就是開啟的,所以當tcp_tw_recycle被開啟后,實際上這種行為就被激活了。
? ? net.ipv4.tcp_tw_recycle又是啥呢,搜索了一下基本上是TIME_WAIT連接的回收參數
? ? 當 net.ipv4.tcp_timestamps 沒有設置(缺省為開啟),并且 net.ipv4.tcp_tw_recycle 也開啟時,這個坑爹的錯誤就出現了,但是注意,只表現在NAT網絡環境中。而且,大多數博客,以及一些大牛們,都有說過要開啟 net.ipv4.tcp_tw_recycle …
? ? ====== 小抄 ======
四.未完成的事項
? ? 上文 http://huoding.com/2012/01/19/142 中提到的:
? ? 1.(未驗證)關閉timestamps后,tw_recycle功能是失效的問題
? ? 2.(未驗證)新的解決TIME_WAIT連接過多的方法:net.ipv4.tcp_max_tw_buckets = 10000 設置一個最大值,不過壞處是系統日志會提示:TCP: time wait bucket table overflow
===============================================================
針對有些用戶能ping通我們的網站,但是連接時超時服務器沒有任何響應,懷疑問題處在了了http的三次握手環節,這是決定通過抓包進行分析:
1、有問題機器的截圖:
2、正常機器的截圖:
3、發現問題
從抓包數據發現,web服務器對出問題機器和正常機器系統的tcp syn包都返回ACK包,但存在問題發出的tcp syn包有時候響應,有時候不響應。不響應時,終端與web服務器之間的tcp連接無法正常建立,導致頁面不能打開。對比這兩種數據包,就在時間戳上有差異,存在問題的機器發出的tcp syn包帶有時間戳,因此懷疑時間戳問題導致的故障。
4、解決問題
既然懷疑是時間戳導致的,那我們就著手分析如果將出現問題的機器的時間戳去掉會不會解決問題。針對帶有時間戳的tcp syn包不響應的問題,查閱了相關資料得知產生問題的原因是出問題系統中的注冊表中有Tcp1323opts這個選項,會導致其在發包時加入時間戳,經過nat之后,如果前面相同的端口被使用過,且時間戳大于這個鏈接發出的syn中的時間戳,服務器上就會忽略掉這個syn,不返會syn-ack消息,表現為用戶無法正常完成tcp3次握手,從而不能打開web頁面。在業務閑時,如果用戶nat的端口沒有被使用過時,就可以正常打開;業務忙時,nat端口重復使用的頻率高,很難分到沒有被使用的端口,從而產生這種問題。
目前看有兩種方法解決:
(1)????是在服務器上修改變量
首先我們先查看一下我們服務器net.ipv4.tcp_timestamps的默認值,如果該值為0測說名不是該問題導致,如果是1我們需要將該值設置為1。
查看默認值的方法:[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_timestamps
修改該值的方法:vim /etc/sysctl.conf? 添加 net.ipv4.tcp_timestamps=0
(2)修改客戶端的注冊表Tcp1323Opts設置為0。
?
備注:
Tcp1323Opts
說明:該參數控制 RFC 1323 時間戳與窗口縮放選項。默認情況下,啟用時間戳與
窗口縮放,但是可以使用標志位進行控制。0 位控制窗口縮放,1 位控制時間戳。
值為0(禁用 RFC 1323 選項)
值為1(僅啟用窗口縮放)
值為2(僅啟用時間戳)
值為3(兩個選項均啟用)
?
net.ipv4.tcp_timestamps=0
說明:時間戳可以避免序列號的卷繞。一個1Gbps的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種“異常”的數據包。這里需要將其關掉。
值為0(禁用時間戳)
值為1(啟用時間戳)
?
只有客戶端和服務端都開啟時間戳的情況下,才會出現能ping通不能建立tcp三次握手的情況,所以做為提供服務的公司,不可能保證所有的用戶都關閉時間戳,這個功能,所以我們必須關閉時間戳,這樣才能給所用用戶提供正常的服務。
轉載于:https://my.oschina.net/tsh/blog/1335116
總結
以上是生活随笔為你收集整理的记一次TCP连接异常故障解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript深拷贝和浅拷贝
- 下一篇: 大数据服务社会的一个有益实践