linux的TCP超時重傳--一次數據斷開鏈接分析

最近生產上發現一個問題,剛開始,應用鏈接數據庫正常,若是長時間沒有業務估計半小時以上,再發起業務時,html

發現應用重連不上數據庫,一直掛在重連那裏,若是重啓應用又能很快連上數據庫(數據庫是Oracle)。後來經數linux

據庫專家的同窗看了後,發現咱們的生產是RAC的,而客戶端配置了TAF,致使在發生會話切換的時候,可能原算法

來的鏈接沒有釋放好,影響了重連。把Oracle客戶端的TAF關掉,重連的問題解決了。但又出現了一個很奇怪的數據庫

現象,就是今天要說的重點問題,若是長時間沒業務的時候仍是斷,並且斷了後執行SQL要15分鐘左右應用才能網絡

返回,這將致使應用在15分鐘內不能服務,應用返回的錯誤是 ORA-03113: end-of-file on communication channeltcp

從這個錯誤看,應該是Oracle客戶端返回了鏈接斷開的錯誤,可是爲何要15分鐘後才返回這個錯誤呢?google

機器的網絡狀況以下:.net

應用主機A ----> FW1(防火牆1) ---->FW2(防火牆2) ----> 數據庫主機(OracleDB)htm

後來經網絡專家的同窗判斷,有多是防火牆設置了會話超時,若是長時間一個會話上沒有數據防火牆就會刪除blog

會話,同時網上也有人遇到相似的狀況:

YQE[G(IFO0]9)UY9VOZ38IH

咱們作了相似的嘗試,放開防火牆的時間限制後,問題沒再出現。可是還有幾個疑問沒有解決:

1.爲何防火牆刪除會話後,主機要等15分鐘?

2.防火牆刪除會話後,會不會通知主機(給主機發RST)?

早上和同事討論,猜想是因爲防火牆刪除了會話,但主機並不知道,有數據庫操做的時候,由Oracle客戶端

發起TCP請求,但因爲防火牆找不到會話,丟棄了這些包(目前是否是丟還不清楚),致使了TCP不停地超時

重發。

查看TCP/IP詳解第一卷的21章節21.2節,都超時重發有這樣的描述:

image

這裏提到9分鐘,不過這本書寫得比較早,猜想linux有所不同,不過原理差不了太多,google了一下,

好像找到了15分鐘的說法, 參考資料[1]中提到:

TCP_RTO_MIN=(HZ/5)=0.2s
TCP_RTO_MAX=(120*HZ)=120s
linear_backoff_thresh = ilog2(120*5)=ilog2(0x258)=9
timeout:未超過linear_backoff_thresh=9的部分按TCP_RTO_MIN 2的指數倍增加,超過的部分按TCP_RTO_MAX線性增加
tcp_time_stamp:當前時鐘時間
例如數據發送階段,sysctl_tcp_retries2=9,則timeout=1023*TCP_RTO_MIN=204.6s;sysctl_tcp_retries2=11時,timeout=1023*TCP_RTO_MIN+2*TCP_RTO_MAX=448.6s
默認sysctl_tcp_retries2=15,timeout=1023*TCP_RTO_MIN+6*TCP_RTO_MAX=920.6s,約15分鐘

是根據RTO及必定的算法算出來的(具體的算法,能夠看參考資料[3])

簡單說,就是若是系統配置重傳次數小於9的話,就是指數增加時間,若是大於9的話,就是最大超時時間。

而linux默認是15,因此恰好是15分鐘,查看咱們主機的配置,確認是15:

[steven@kfjk2 ~]$ cat /proc/sys/net/ipv4/tcp_retries2
15

如今還有一個問題沒弄清楚,就是防火牆刪除會話後,是否會通知主機?如今看起來應該是不會的,至少在主機上是沒收到

防火牆的RST,因爲兩個防火牆的兩個廠商不同,也有多是一個吃掉另一個的包也說不定。假如刪除會話後,在原來

的會話上來有包上來,是重建會話呢?仍是直接把包丟棄?仍是發RST呢?從目前主機的現象來看,猜想是:

防火牆刪除會話後,不會通知主機也就是不會給主機發RST,當有新包上來,找不到鏈接,但不是S包的時候,直接丟棄,

致使主機用完了重發次數後,本身發RST後給應用報斷開鏈接。

不過。。。以上的東東都是根據現象來猜想的,最有效的辦法是捉出tcpdump包來看,但因爲是生產不敢亂動,也先這樣吧!

僅以此記,爲避免之後踩坑,同時開發人員也要關心網絡部署,當時我並無考慮中間有兩個防火牆。

【參考資料】

  1. linux TCP超時重傳
  2. 【探討】linux下的tcp協議棧超時重傳機制
  3. TCP/IP重傳超時--RTO
相關文章
相關標籤/搜索