吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

TIME_WAIT狀態的優化思路

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-10 10:44 ? 次閱讀
  1. 為什么需要TIME_WAIT狀態?為什么TIME_WAIT的時長是2*MSL?

原因1:防止連接關閉時四次揮手中的最后一次ACK丟失:

TCP需要保證每一包數據都可靠的到達對端,包括正常連接狀態下的業務數據報文,以及用于連接管理的握手、揮手報文,這其中在四次揮手中的最后一次ACK報文比較特殊,TIME_WAIT狀態就是為了應對最后一條ACK丟失的情況。

TCP保證可靠傳輸的前提是收發兩端分別維護關于這條連接的狀態信息(TCB控制塊),當發生丟包時進行ARQ重傳。如果連接釋放了,就無法進行重傳,也就無法保證發生丟包時的可靠傳輸。

對于最后一條ACK,如果沒有TIME_WAIT狀態,主動關閉一方(客戶端)就會在收到對端(服務器)的FIN并回復ACK后 直接從FIN_WAIT_2 進入 CLOSED狀態,并釋放連接,銷毀TCB實例。此時如果最后一條ACK丟失,那么服務器重傳的FIN將無人處理,最后導致服務器長時間的處于 LAST_ACK狀態而無法正常關閉(服務器只能等到達到FIN的最大重傳次數后關閉)。

至于將TIME_WAIT的時長設置為 2MSL,是因為報文在鏈路中的最大生存時間為MSL(Maximum Segment Lifetime),超過這個時長后報文就會被丟棄。TIME_WAIT的時長則是:最后一次ACK傳輸到服務器的時間 + 服務器重傳FIN 的時間,即為 2MSL。

原因2:防止新連接收到舊鏈接的TCP報文:

TCP使用四元組區分一個連接(源端口、目的端口、源IP、目的IP),如果新、舊連接的IP與端口號完全一致,則內核協議棧無法區分這兩條連接。

2*MSL 的時間足以保證兩個方向上的數據都被丟棄,使得原來連接的數據包在網絡中都自然消失,再出現的數據包一定是新連接上產生的。

MSL(Maximum Segment Lifetime) 報文最大生存時間在不同操作系統中的具體值:

Windows : 2 min
Linux(Ubuntu) : 60 s
Unix : 30 s

2. TIME_WAIT對連接并發數的影響(TIME_WAIT過多的危害):

在Linux系統中,MSL = 60 s, 2 * MSL = 120 s,所以一條待關閉的TCP連接會在 TIME_WAIT 狀態等待 120秒(2分鐘)。

當連接處于TIME_WAIT狀態時仍會占用系統資源(fd、端口、內存),當系統的并發連接數很大時,過多的TIME_WAIT狀態的連接會對系統的并發量造成影響。

(1)對服務器的影響:

由于服務器一般只需要監聽一個固定的端口,所以服務器所能支持的最大并發出數的上限取決于系統套接字描述符fd的大小,以及服務器的內存大小。

fd:

Linux中一個進程 所能打開的fd的最大數量默認為 1024 個,可通過 "ulimit -n (+指定數量)" 進行修改。

Linux系統所能支持的fd最大值在 /proc/sys/fs/fd-max 文件中可以查看,系統當前的fd使用情況可以通過 /proc/sys/fs/fd-nr 查看。(本機上的fd-max的值為:1221842,即100W級。實際上fd的最大值同樣也取決于系統內存的大小)

內存:

假設每一個TCP連接需要開辟 “4k的接收緩沖區 + 4k的發送緩沖區 = 8k”,1W的并發連接需要80M內存,10W并發需要800M,100W并發需要8G內存。

綜上,服務器的并發數主要受限于系統內存的大小,當 TIME_WAIT 狀態的連接過多時,會導致消耗的內存增加,這一點可以通過擴展服務器的內存來解決。

(2)對客戶端的影響:

客戶端的并發數主要受限于端口數量。

一種典型的場景是:高并發短連接(“短連接”表示“業務處理+傳輸數據”的時間遠遠小于TIME_WAIT超時的時間)。

在這種場景下,客戶端可能會消耗大量的端口(例如取一個Web網頁,1秒鐘的HTTP短連接處理完業務數據,卻需要 2分鐘的TIME_WAIT等待時間,在這段時間內客戶端上的這個端口是無法被其他連接使用的,如果新建連接則需要使用另外的端口號),Linux系統的最大端口為65535,除去系統使用的端口號,假設網絡進程可使用的端口有 6W個,由于TIME_WAIT狀態下在 2*MSL(120秒)內無法再被使用,這就限制了客戶端的連接速率為 60000 / 120秒 = 500 次/秒, 這是一個非常低的并發率。

同時,大量的TIME_WAIT連接同樣會消耗客戶端的內存,所以客戶端的最大并發數取決于 端口號與內存 二者中的最小值。

3. 優化TIME_WAIT的方法:

方法1:修改內核參數 tcp_tw_reuse:

net.ipv4.tcp_tw_reuse = 1;
net.ipv4.tcp_timestamp = 1;

注意:tcp_tw_reuse 內核參數只在調用 connect() 函數時起作用,所以只能用于客戶端(主動連接的一端)。

tcp_tw_reuse 的作用是:在調用connect()函數時,內核會隨機找一個處于TIME_WAIT狀態 超過1秒 的連接給新連接復用。(超時時間由 tcp_timestamp設置,默認為 1秒)

這種方式可以縮短 TIME_WAIT 的等待時間。

方法2:修改內核參數 tcp_max_tw_buckets:

net.ipv4.tcp_max_tw_buckets 參數的默認值為18000,當系統中處于 TIME_WAIT 狀態的連接數量超過閾值,系統會將后面的TIME_WAIT連接重置。

由于這種方法會直接重置連接,因此需要謹慎使用。

方法3:設置套接字選項 SO_LINGER:

SO_LINGER選項用于設置 調用close() 關閉TCP連接時的行為,注意 SO_LINGER選項會使用RST復位報文段取代 FIN-ACK四次揮手的過程,設置了SO_LINGER選項的一方在調用close() 時會直接發送一個RST,接收端收到后復位連接,不會回復任何響應。

這樣做的弊端是導致TCP緩沖區中的數據被丟棄。

正常情況下,調用close后的缺省行為是:如果有待發送的數據殘留在發送緩沖區中,內核協議棧將繼續將這些數據發送給接收端后才關閉連接,走正常的四次揮手流程;

設置SO_LINGER后,立即關閉連接,通過RST分組,發送緩沖區如果有未發送的數據,將會被丟棄,主動關閉的一方跳過TIME_WAIT狀態,直接進入CLOSED(也跳過了FIN_WAIT_1 和 FIN_WAIT_2)。

SO_LINGER的另一種更溫和的實現方式是設置一個超時時間(so_linger.l_linger),而不是直接關閉。

應用程序調用close后進入睡眠,內核協議棧負責發送緩沖中殘留的待發送數據,如果在 l_linger 超時時間內發送完畢,則走正常的四次揮手流程;如果超時未發送完,則發送RST強制關閉連接,并丟棄發送緩沖區中其余的數據(接收端收到RST后也會丟棄接收緩沖區中的數據),并且發送端close()函數返回 EWOULDBLOCK。

綜上,如果只是單純為了規避 TIME_WAIT 狀態,使用 SO_LINGER并不是一個好主意,因為它會在調用close關閉連接時 使用RST強制關閉連接,這可能會導致 發送緩沖區、接收緩沖區 中還未處理完的數據被丟棄。

struct linger so_linger;
so_linger.l_onoff = 1; //0表示關閉,忽略l_linger的值;非0表示打開
so_linger.l_linger = 0; //設置等待時間,等于0則表示立即關閉

setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));

方法4:設置套接字選項 SO_REUSEADDR:

SO_REUSEADDR 選項用于通知內核:

如果端口忙,并且端口對應的TCP連接狀態為TIME_WAIT,則可以重用端口;

如果端口忙,并且端口對應的TCP連接處于其他狀態(非TIME_WAIT),則返回 “Address already in use” 的錯誤信息。

設置SO_REUSEADDR的風險是可能會導致新連接上收到舊連接的數據(復用了舊連接的端口,導致新舊連接的四元組完全一致,內核協議棧無法區分這兩個連接)。

SO_REUSEADDR 選項并沒像 tcp_tw_reuse 那樣同時提供一個 tcp_timestamp 參數可以設置 TIME_WAIT的等待時長。

綜上,對TIME_WAIT狀態的優化思路是盡量縮小等待時長,而不是暴力的直接關閉(可能會引起新連接收到舊連接數據的風險),也不要直接發送RST復位連接(可能會引起發送、接收緩沖區中的數據丟失),所以使用修改內核參數 tcp_tw_reuse 參數是最保險的方式,通過根據實際網絡情況和應用場景適當的調節 tcp_timestamp 的值,可以達到縮小 TIME_WAIT 等待時長,進而減少系統中同一時刻處于 TIME_WAIT 狀態的連接數量的目的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7140

    瀏覽量

    89581
  • 操作系統
    +關注

    關注

    37

    文章

    6895

    瀏覽量

    123748
  • TIME
    +關注

    關注

    0

    文章

    13

    瀏覽量

    14335
收藏 人收藏

    評論

    相關推薦

    CC3200 socket狀態如何查詢?

    已,正在等待本地套接字的關閉確認 FIN_WAIT_2 套接字已關閉,正在等待遠程套接字關閉TIME_WAIT 這個套接字已經關閉,正在等待遠程套接字的關閉傳送
    發表于 05-06 11:00

    WEB CLOSE_WAIT socket不釋放如何解決呢

    :web連接過后發現有大量的TIME_WAIT狀態的socket,怎么限制WEB的并發數量,把rtConfig.h中的這個宏改小到多少合適呢?如果太小了會不會導致web登錄不了的情況?#define WEBNET_CONN_MAX 8
    發表于 09-27 10:06

    GPRS優化思路總結報告

    GPRS優化思路總結報告:一、概述 2二、無線優化思路 2三、(E)GPRS網絡資源容量分析優化 53.1、
    發表于 07-27 21:29 ?26次下載

    狀態思路在單片機程序設計中的應用

    狀態思路在單片機程序設計中的應用 狀態機的概念狀態機是軟件編程中的一個重要概念。比這個概念更重要的是對它的靈活應用。在一個思路清晰而且高
    發表于 02-09 11:25 ?1w次閱讀
    <b class='flag-5'>狀態</b>機<b class='flag-5'>思路</b>在單片機程序設計中的應用

    實時時鐘的選擇與優化-Real-Time-Clock Sel

    Abstract: This application note describes real-time clock (RTC) and crystal selection criteria
    發表于 04-21 10:35 ?3535次閱讀
    實時時鐘的選擇與<b class='flag-5'>優化</b>-Real-<b class='flag-5'>Time</b>-Clock Sel

    GPRS優化思路總結報告_李青春

    (E)GPRS 優化思路通信網絡優化,GSM上網,PDCH,EDGEGPRS.
    發表于 01-14 15:21 ?4次下載

    分析在java中sleep和wait的不同

    的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。 在調用sleep()方法的過程中,線程不會釋放對象鎖。 而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify(
    發表于 09-27 14:41 ?0次下載

    服務器產生大量的TIME_WAIT究竟是因為什么

    寫在開頭,大概 4 年前,聽到運維同學提到 TIME_WAIT 狀態的 TCP 連接過多的問題,但是當時沒有去細琢磨;最近又聽人說起,是一個新手進行壓測過程中,遇到的問題,因此,花點時間,細深究一下
    的頭像 發表于 10-13 16:47 ?1.4w次閱讀
    服務器產生大量的<b class='flag-5'>TIME_WAIT</b>究竟是因為什么

    學習Linux命令的正確姿勢

    短時間后,所有的 TIME_WAIT 全都消失,被回收,端口包括服務,均正常。即,在高并發的場景下,TIME_WAIT 連接存在,屬于正?,F象。
    的頭像 發表于 08-31 10:27 ?518次閱讀

    關于手動伺服優化調整思路分享

    常規的伺服優化調整一般需要用到SERVO GUIDE 軟件,而對于一些不是很懂該軟件操作的客戶或者在現場無法進行在線聯網調整的情況下,手動調整就顯得比較關鍵實用,在此提供手動伺服優化調整思路。
    發表于 01-29 12:18 ?2917次閱讀

    圖解Java多線程中的wait()和notify()方法

    wait()和notify()是Object類的方法,用于線程的等待與喚醒,必須搭配synchronized 鎖來使用。
    的頭像 發表于 03-22 09:29 ?3212次閱讀

    KUKA機器人WAIT FOR運用條件

    WAIT FOR … : 等至條件已滿足 WAITFOR 停止程序,直到已滿足特定的條件。然后程序繼續運行。WAIT FOR 將觸發預進停止。 編譯器識別不到由于錯誤的表達而使表達式無法采用數值
    的頭像 發表于 06-13 11:31 ?3437次閱讀

    TCP和UDP分別是什么 TCP和UDP協議各有什么特點

    在 TCP 四次揮手的最后一步,客戶端進入 TIME_WAIT 狀態,需要等待一段時間再進入 CLOSED 狀態。等待時間通常是兩個最大報文段生命周期,即 2MSL,這是為了確保服務器端能夠收到客戶端發送的最后一個 ACK 報文
    的頭像 發表于 08-09 12:34 ?4513次閱讀

    TIME_WAIT是什么

    ,遇到了這道題目: 生產環境 Nginx 后端服務大量 TIME-WAIT 的解決步驟 這里小編給大家做一下系統化、體系化的梳理,使得大家可以充分展示一下大家雄厚的 “技術肌肉”,讓面試官愛到 “不能自已、口水直流”。 基礎知識 TIME_WAIT是什么? 在構建TCP客
    的頭像 發表于 11-10 14:48 ?707次閱讀
    <b class='flag-5'>TIME_WAIT</b>是什么

    為什么要有TIME_WAIT狀態

    首先我們說下狀態 TIME_WAIT 出現的原因 TCP的新建連接,斷開連接的流程和各個狀態,如下圖所示 由上圖可知:TIME_WAIT 是主動斷開連接的一方會出現的,客戶端,服務器都
    的頭像 發表于 11-13 11:26 ?2273次閱讀
    為什么要有<b class='flag-5'>TIME_WAIT</b><b class='flag-5'>狀態</b>
    中原百家乐官网的玩法技巧和规则| 百家乐官网园sun811| 大发888娱乐城qq服务| 百家乐网站排行| 免费百家乐官网在线| 棋牌赚钱| 百家乐群b28博你| 新葡京百家乐官网的玩法技巧和规则 | 百家乐娱乐网址| 百家乐官网网上娱乐场开户注册 | 太阳城洋伞| 赌场百家乐玩法介绍| 百家乐官网有没有单机版的| 金沙百家乐官网现金网| 丹东亿酷棋牌下载| 百家乐娱乐网会员注册| 百家乐官网论坛| 百家乐官网自动算牌软件| 枞阳县| 棋牌类玩具| 凱旋門百家乐娱乐城| 百家乐和抽水官网| 迪士尼百家乐官网的玩法技巧和规则 | 百家乐官网前四手下注之观点| 孟津县| 蜀都棋牌下载| 免费百家乐统计| 百家乐赌场彩| 杨公24山属性| 在线百家乐官网合作| 百家乐官网拍是什么| 金沙娱乐城| 大发888 打法888| 百家乐五铺的缆是什么意思| 百家乐园sun811.com| 24山在风水学中应用| 大世界百家乐官网娱乐平台| 百家乐官网闲单开多少| 博彩娱乐网| 网络博彩公司| 大发888娱乐场and|