背景:
內網有一台nginx伺服器提供外網服務,時常出現訪問異常或者重連現象,此故障出現均在外網不在內網,內網訪問一切正常,未出現此類故障:
當開啟nat時丟棄資料報增加。
客戶端顯示:
nginx伺服器顯示
分析處理過程:
1、內網和外網訪問的區別在於內網訪問使用私網位址直接訪問nginx伺服器,外網和內網之間使用一台防火牆進行連線,nginx和公網位址在防火牆上做了位址對映。
2、懷疑是出口防火牆的問題,經過防火牆的廠家進行了檢查,分三部分:
> 內到外的位址對映是正常的,沒出現任何異常。
> 同為對映的郵件,dns等伺服器沒出現此類問題。
> 異常的就集中在和nginx之間的tcp連線異常,經常丟包造成。
在中間進行抓包分析情況如下:
抓包顯示中間的異常資料報只有去往nginx的資料報卻沒有會回來的資料報。
3、後聯合廠家和nginx管理人員溝通提出可能是由於防火牆的nat時間戳造成的,nginx伺服器端修改tcp_tw_recycle狀態為down後恢復正常。
4、通過參考網上的資料,我們定位到問題發生的原因:我們的web server的
linux
內做過調整,開啟了
net.ipv4.tcp_tw_recycle
,在防火牆只做
nat的情況下,觸發了大量的
tcp建連失敗。
啟用time-wait狀態
sockets
的快速**,這個選項不推薦啟用。在
nat(network address translation)
網路下,會導致大量的
tcp連線建立錯誤。
下面我們來具體說下,首先解釋下tcp的
time_wait
狀態:
開啟net.ipv4.tcp_tw_recycle的目的,就是希望能夠加快
time_wait
狀態的**,當然這個選項的生效也依賴於
net.ipv4.tcp_timestamps
的開啟(預設就是開啟的)。
當開啟了tcp_tw_recycle選項後,當連線進入
time_wait
狀態後,會記錄對應遠端主機最後到達分節的時間戳。如果同樣的主機有新的分節到達,且時間戳小於之前記錄的時間戳,即視為無效,相應的資料報會被丟棄
當防火牆啟用nat模式時,客戶端
tcp請求到達防火牆,修改目的位址(
ip+埠號)後便**給後端伺服器,而客戶端時間戳資料沒有變化。對於後端
web server
,請求的源位址是防火牆,所以從後端伺服器的角度看,原本不同客戶端的請求經過
lvs的**,就可能會被認為是同乙個連線,加之不同客戶端的時間可能不一致,所以就會出現時間戳錯亂的現象,於是後面的資料報就被丟棄了。
5、問題解決。
解決辦法是linux核心引入tcp_tw_timeout
開關,該開關可以動態設定time_wait 時間,加速**time_wait 狀態,從而可以關閉tcp_tw_recycle
,避免上述問題。
乙個memset引發的血案
前幾天做了一道bst題,提交了幾次都是wa,今天抽空拿了出來仔細瞧瞧總算被我發現禍頭根源.總結原因還在於自己對memset不太了解,以前用對估計也是瞎貓撞見死耗子 memset的介紹 void memset void buffer,int ch,size t count buffer 指向某段記憶體...
乙個分號引發的「血案」
再多的表情也無法詮釋我現在的心情!a b for matrices 這是很水的一道題,然而卻整整折騰了我2個多小時。從晚上6點多開始,花了沒幾分鐘就把 敲好了,可是資料一測,竟然不對,然後就開始找問題,找了很久,我竟然都還沒看出問題在哪,越找心裡越不爽,這麼做明明對的呀,一執行怎麼就錯了呢?一直到了...
乙個strlen引發的血案
部分測試 原來是這樣的 int decryptrelation aesdecryptfromfiletobytes const std string in file path,unsigned char out data,const char aes encrypt key,int in data ...