1. 程式人生 > >TCP/IP詳解--TCP連線中TIME WAIT狀態過多

TCP/IP詳解--TCP連線中TIME WAIT狀態過多

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                TIMEWAIT狀態本身和應用層的客戶端或者伺服器是沒有關係的。僅僅是主動關閉的一方,在使用FIN|ACK|FIN|ACK四分組正常關閉TCP連線的時候會出現這個TIMEWAIT。伺服器在處理客戶端請求的時候,如果你的程式設計為伺服器主動關閉,那麼你才有可能需要關注這個TIMEWAIT狀態過多的問題。如果你的伺服器設計為被動關閉,那麼你首先要關注的是CLOSE_WAIT。


原則

TIMEWAIT並不是多餘的 在TCP協議被創造,經歷了大量的實際場景實踐之後TIMEWAIT出現了,因為TCP主動關閉連線的一方需要TIMEWAIT狀態,它是我們的朋友。這是UNIX網路程式設計》的作者----Steven對TIMEWAIT的態度。

TIMEWAIT是友好的

    TCP要保證在所有可能的情況下使得所有的資料都能夠被正確送達。當你關閉一個socket時,主動關閉一端的socket將進入TIME_WAIT狀態,而被動關閉一方則轉入CLOSED狀態,這的確能夠保證所有的資料都被傳輸。當一個socket關閉的時候,是通過兩端四次握手完成的,當一端呼叫close()時,就說明本端沒有資料要傳送了。這好似看來在握手完成以後,socket就都可以處於初始的CLOSED狀態了,其實不然。原因是這樣安排狀態有兩個問題, 首先,我們沒有任何機制保證最後的一個ACK能夠正常傳輸,第二,網路上仍然有可能有殘餘的資料包(wandering duplicates),我們也必須能夠正常處理。

TIMEWAIT就是為了解決這兩個問題而生的。

1.假設最後一個ACK丟失了,被動關閉一方會重發它的FIN。主動關閉一方必須維持一個有效狀態資訊(TIMEWAIT狀態下維持),以便能夠重發ACK。如果主動關閉的socket不維持這種狀態而進入CLOSED狀態,那麼主動關閉的socket在處於CLOSED狀態時,接收到FIN後將會響應一個RST。被動關閉一方接收到RST後會認為出錯了。如果TCP協議想要正常完成必要的操作而終止雙方的資料流傳輸,就必須完全正確的傳輸四次握手的四個節,不能有任何的丟失。這就是為什麼socket在關閉後,仍然處於TIME_WAIT狀態的第一個原因,因為他要等待以便重發ACK。

2.假設目前連線的通訊雙方都已經呼叫了close(),雙方同時進入CLOSED的終結狀態,而沒有走TIME_WAIT狀態。會出現如下問題,現在有一個新的連線被建立起來,使用的IP地址與埠與先前的完全相同,後建立的連線是原先連線的一個完全複用。還假定原先的連線中有資料報殘存於網路之中,這樣新的連線收到的資料報中有可能是先前連線的資料報。為了防止這一點,TCP不允許新連線複用TIME_WAIT狀態下的socket。處於TIME_WAIT狀態的socket在等待兩倍的MSL時間以後(之所以是兩倍的MSL,是由於MSL是一個數據報在網路中單向發出到認定丟失的時間,一個數據報有可能在傳送途中或是其響應過程中成為殘餘資料報,確認一個數據報及其響應的丟棄的需要兩倍的MSL),將會轉變為CLOSED狀態。這就意味著,一個成功建立的連線,必然使得先前網路中殘餘的資料報都丟失了。


大量TIMEWAIT在某些場景中導致的令人頭疼的業務問題

大量TIMEWAIT出現,並且需要解決的場景
      
在高併發短連線的TCP伺服器上,當伺服器處理完請求後立刻按照主動正常關閉連線。。。這個場景下,會出現大量socket處於TIMEWAIT狀態。如果客戶端的併發量持續很高,此時部分客戶端就會顯示連線不上。
我來解釋下這個場景。主動正常關閉TCP連線,都會出現TIMEWAIT。為什麼我們要關注這個高併發短連線呢?有兩個方面需要注意
1. 高併發可以讓伺服器在短時間範圍內同時佔用大量埠,而埠有個0~65535的範圍,並不是很多,刨除系統和其他服務要用的,剩下的就更少了
2. 在這個場景中,短連線表示“業務處理+傳輸資料的時間 遠遠小於 TIMEWAIT超時的時間”的連線。這裡有個相對長短的概念,比如,取一個web頁面,1秒鐘的http短連線處理完業務,在關閉連線之後,這個業務用過的埠會停留在TIMEWAIT狀態幾分鐘,而這幾分鐘,其他HTTP請求來臨的時候是無法佔用此埠的。單用這個業務計算伺服器的利用率會發現,伺服器幹正經事的時間和埠(資源)被掛著無法被使用的時間的比例是 1:幾百,伺服器資源嚴重浪費。(說個題外話,從這個意義出發來考慮伺服器效能調優的話,長連線業務的服務就不需要考慮TIMEWAIT狀態。同時,假如你對伺服器業務場景非常熟悉,你會發現,在實際業務場景中,一般長連線對應的業務的併發量並不會很高
綜合這兩個方面,持續的到達一定量的高併發短連線,會使伺服器因埠資源不足而拒絕為一部分客戶服務。同時,這些埠都是伺服器臨時分配,無法用SO_REUSEADDR選項解決這個問題:(

一對矛盾

TIMEWAIT既友好,又令人頭疼。
但是我們還是要抱著一個友好的態度來看待它,因為它盡它的能力保證了伺服器的健壯性。


可行而且必須存在,但是不符合原則的解決方式

1. linux沒有在sysctl或者proc檔案系統暴露修改這個TIMEWAIT超時時間的介面,可以修改核心協議棧程式碼中關於這個TIMEWAIT的超時時間引數,重編核心,讓它縮短超時時間,加快回收;
2. 利用SO_LINGER選項的強制關閉方式,發RST而不是FIN,來越過TIMEWAIT狀態,直接進入CLOSED狀態。詳見我的博《TCP之選項SO_LINGER


我如何看待這個問題

為什麼說上述兩種解決方式我覺得可行,但是不符合原則?
我首先認為,我要依靠TIMEWAIT狀態來保證我的伺服器程式健壯,網路上發生的亂七八糟的問題太多了,我先要服務功能正常。
那是不是就不要效能了呢?並不是。如果伺服器上跑的短連線業務量到了我真的必須處理這個TIMEWAIT狀態過多的問題的時候,我的原則是儘量處理,而不是跟TIMEWAIT幹上,非先除之而後快:)如果儘量處理了,還是解決不了問題,仍然拒絕服務部分請求,那我會採取分機器的方法,讓多臺機器來抗這些高併發的短請求。持續十萬併發的短連線請求,兩臺機器,每臺5萬個,應該夠用了吧。一般的業務量以及國內大部分網站其實並不需要關注這個問題,一句話,達不到需要關注這個問題的訪問量。
真正地必須使用上述我認為不合理的方式來解決這個問題的場景有沒有呢?答案是有。
像淘寶、百度、新浪、京東商城這樣的站點,由於有很多靜態小圖片業務,如果過度分服會導致需要上線大量機器,多買機器多花錢,得多配機房,多配備運維工程師來守護這些機器,成本增長非常嚴重。。。這個時候就要盡一切可能去優化。
題外話,伺服器上的技術問題沒有絕對,一切都是為業務需求服務的。

如何儘量處理TIMEWAIT過多

sysctl改兩個核心引數就行了,如下:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
簡單來說,就是開啟系統的TIMEWAIT重用和快速回收,至於怎麼重用和快速回收,這個問題我沒有深究,實際場景中這麼做確實有效果。用netstat或者ss觀察就能得出結論。
還有些朋友同時也會開啟syncookies這個功能,如下:
net.ipv4.tcp_syncookies = 1

開啟這個syncookies目的實際上是:“在伺服器資源(並非單指埠資源,拒絕服務有很多種資源不足的情況)不足的情況下,儘量不要拒絕TCP的syn(連線)請求,儘量把syn請求快取起來,留著過會兒有能力的時候處理這些TCP的連線請求”。
如果併發量真的非常非常高,開啟這個其實用處不大。
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述 我們對Markdown編輯器進行了一些功能拓展與語法支援,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫部落格:
  1. 全新的介面設計 ,將會帶來全新的寫作體驗;
  2. 在創作中心設定你喜愛的程式碼高亮樣式,Markdown 將程式碼片顯示選擇的高亮樣式 進行展示;
  3. 增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
  4. 全新的 KaTeX數學公式 語法;
  5. 增加了支援甘特圖的mermaid語法1 功能;
  6. 增加了 多螢幕編輯 Markdown文章功能;
  7. 增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設定 等功能,功能按鈕位於編輯區域與預覽區域中間;
  8. 增加了 檢查列表 功能。

功能快捷鍵

撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入程式碼:Ctrl/Command + Shift + K
插入連結:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G

合理的建立標題,有助於目錄的生成

直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支援6級標題。有助於使用TOC語法後生成一個完美的目錄。

如何改變文字的樣式

強調文字 強調文字

加粗文字 加粗文字

標記文字

刪除文字

引用文字

H2O is是液體。

210 運算結果是 1024.

插入連結與圖片

連結: link.

圖片: Alt

帶尺寸的圖片: Alt

當然,我們為了讓使用者更加便捷,我們增加了圖片拖拽功能。

如何插入一段漂亮的程式碼片

部落格設定頁面,選擇一款你喜歡的程式碼片高亮樣式,下面展示同樣高亮的 程式碼片.

// An highlighted block var foo = 'bar'; 

生成一個適合你的列表

  • 專案
    • 專案
      • 專案
  1. 專案1
  2. 專案2
  3. 專案3
  • 計劃任務
  • 完成任務

建立一個表格

一個簡單的表格是這麼建立的:

專案 Value
電腦 $1600
手機 $12
導管 $1

設定內容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文字居中 第二列文字居右 第三列文字居左

SmartyPants

SmartyPants將ASCII標點字元轉換為“智慧”印刷標點HTML實體。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

建立一個自定義列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何建立一個註腳

一個具有註腳的文字。2

註釋也是必不可少的

Markdown將文字轉換為 HTML

KaTeX數學公式

您可以使用渲染LaTeX數學表示式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n 1 ) ! n N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N 是通過尤拉積分

Γ ( z ) = 0 t z 1 e t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.

你可以找到更多關於的資訊 LaTeX 數學表示式here.

新的甘特圖功能,豐富你的文章

gantt
        dateFormat  YYYY-MM-DD
        title Adding GANTT diagram functionality to mermaid
        section 現有任務
        已完成               :done,    des1, 2014-01-06,2014-01-08
        進行中               :active,  des2, 2014-01-09, 3d
        計劃一               :         des3, after des2, 5d
        計劃二               :         des4, after des3, 5d
  • 關於 甘特圖 語法,參考 這兒,

UML 圖表

可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖::

這將產生一個流程圖。:

  • 關於 Mermaid 語法,參考 這兒,

FLowchart流程圖

我們依舊會支援flowchart的流程圖:

  • 關於 Flowchart流程圖 語法,參考 這兒.

匯出與匯入

匯出

如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章匯出 ,生成一個.md檔案或者.html檔案進行本地儲存。

匯入

如果你想載入一篇你寫過的.md檔案或者.html檔案,在上方工具欄可以選擇匯入功能進行對應副檔名的檔案匯入,
繼續你的創作。


  1. mermaid語法說明 ↩︎

  2. 註腳的解釋 ↩︎