HOME 首頁
SERVICE 服務(wù)產(chǎn)品
XINMEITI 新媒體代運營
CASE 服務(wù)案例
NEWS 熱點資訊
ABOUT 關(guān)于我們
CONTACT 聯(lián)系我們
創(chuàng)意嶺
讓品牌有溫度、有情感
專注品牌策劃15年

    出現(xiàn)大量time_wait狀態(tài)(大量timewait狀態(tài)的后果)

    發(fā)布時間:2023-03-13 13:06:52     稿源: 創(chuàng)意嶺    閱讀: 121        問大家

    大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關(guān)于出現(xiàn)大量time_wait狀態(tài)的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。

    ChatGPT國內(nèi)免費在線使用,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等

    只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準(zhǔn),寫出的就越詳細(xì),有微信小程序端、在線網(wǎng)頁版、PC客戶端

    官網(wǎng):https://ai.de1919.com

    本文目錄:

    出現(xiàn)大量time_wait狀態(tài)(大量timewait狀態(tài)的后果)

    一、netstat查詢到本機(jī)的有大量127.0.0.1各種不同端口處于TIME_WAIT狀態(tài),是什么原因?

    電腦網(wǎng)絡(luò)問題。根據(jù)你的描述,netstat查詢到本機(jī)的有大量127.0.0.1各種不同端口處于TIME_WAIT狀態(tài),是因為:

    1,有程序或者病毒預(yù)留了這些端口。

    2,系統(tǒng)沒有優(yōu)化,開啟了過多無用端口。

    二、開始運行CMD 里打 netstat -an 出現(xiàn)一堆TIME_WAIT 怎么回事

    1:連接協(xié)議 udp tcp

    2:對應(yīng)的本地地址及連接端口

    3:對應(yīng)的遠(yuǎn)程地址及端口

    4:連接狀態(tài)

    LISTENING  監(jiān)聽

    TIME_WAIT  超時

    ESTABLISHED  正在通信

    三、【TCP】 tcp四次揮手狀態(tài) TIME_WAIT

    首先,我們需要明確, 只有主動斷開的那一方才會進(jìn)入 TIME_WAIT 狀態(tài) ,且會在那個狀態(tài)持續(xù) 2 個 MSL(Max Segment Lifetime)。

    為了講清楚 TIME_WAIT,需要先介紹一下 MSL 的概念。

    MSL(報文最大生存時間)是 TCP 報文在網(wǎng)絡(luò)中的最大生存時間。這個值與 IP 報文頭的 TTL 字段有密切的關(guān)系。

    IP 報文頭中有一個 8 位的存活時間字段(Time to live, TTL)如下圖。 這個存活時間存儲的不是具體的時間,而是一個 IP 報文最大可經(jīng)過的路由數(shù),每經(jīng)過一個路由器,TTL 減 1,當(dāng) TTL 減到 0 時這個 IP 報文會被丟棄。

    TTL 經(jīng)過路由器不斷減小的過程如下圖所示,假設(shè)初始的 TTL 為 12,經(jīng)過下一個路由器 R1 以后 TTL 變?yōu)?11,后面每經(jīng)過一個路由器以后 TTL 減 1

    從上面可以看到 TTL 說的是「跳數(shù)」限制而不是「時間」限制,盡管如此我們依然假設(shè) 最大跳數(shù)的報文在網(wǎng)絡(luò)中存活的時間不可能超過 MSL 秒 。

    Linux 的套接字實現(xiàn)假設(shè) MSL 為 30 秒,因此在 Linux 機(jī)器上 TIME_WAIT 狀態(tài)將持續(xù) 60秒。

    要構(gòu)造一個 TIME_WAIT 非常簡單,只需要建立一個 TCP 連接,然后斷開某一方連接,主動斷開的那一方就會進(jìn)入 TIME_WAIT 狀態(tài),我們用 Linux 上開箱即用的 nc 命令來構(gòu)造一個。

    過程如下圖:

    在機(jī)器 c2 上用nc -l 8888啟動一個 TCP 服務(wù)器

    在機(jī)器 c1 上用 nc c2 8888 創(chuàng)建一條 TCP 連接

    在機(jī)器 c1 上用 Ctrl+C 停止 nc 命令,隨后在用netstat -atnp | grep 8888查看連接狀態(tài)。

    第一個原因是:數(shù)據(jù)報文可能在發(fā)送途中延遲但最終會到達(dá),因此要等老的“迷路”的重復(fù)報文段在網(wǎng)絡(luò)中過期失效,這樣可以避免用相同源端口和目標(biāo)端口創(chuàng)建新連接時收到舊連接姍姍來遲的數(shù)據(jù)包,造成數(shù)據(jù)錯亂。

    比如下面的例子

    假設(shè)客戶端 10.211.55.2 的 61594 端口與服務(wù)端 10.211.55.10 的 8080 端口一開始建立了一個 TCP 連接。

    假如客戶端發(fā)送完 FIN 包以后不等待直接進(jìn)入 CLOSED 狀態(tài),老連接 SEQ=3 的包因為網(wǎng)絡(luò)的延遲。過了一段時間 相同 的 IP 和端口號又新建了另一條連接,這樣 TCP 連接的四元組就完全一樣了。

    恰好 SEQ 因為回繞等原因 也正好相同,那么 SEQ=3 的包就無法知道到底是舊連接的包還是新連接的包了,造成新連接數(shù)據(jù)的混亂。

    TIME_WAIT 等待時間是 2 個 MSL,已經(jīng)足夠讓一個方向上的包最多存活 MSL 秒就被丟棄,保證了在創(chuàng)建新的 TCP 連接以后,老連接姍姍來遲的包已經(jīng)在網(wǎng)絡(luò)中被丟棄消逝,不會干擾新的連接。

    第二個原因是確??煽繉崿F(xiàn) TCP 全雙工終止連接。

    關(guān)閉連接的四次揮手中,最終的 ACK 由主動關(guān)閉方發(fā)出,如果這個 ACK 丟失,對端(被動關(guān)閉方)將重發(fā) FIN,如果主動關(guān)閉方不維持 TIME_WAIT 直接進(jìn)入 CLOSED 狀態(tài),則無法重傳 ACK,被動關(guān)閉方因此不能及時可靠釋放。

    如果四次揮手的第 4 步中客戶端發(fā)送了給服務(wù)端的確認(rèn) ACK 報文以后不進(jìn)入 TIME_WAIT 狀態(tài),直接進(jìn)入 CLOSED狀態(tài),然后重用端口建立新連接會發(fā)生什么呢?

    如下圖所示

    主動關(guān)閉方如果馬上進(jìn)入 CLOSED 狀態(tài),被動關(guān)閉方這個時候還處于LAST-ACK狀態(tài),主動關(guān)閉方認(rèn)為連接已經(jīng)釋放,端口可以重用了, 如果使用相同的端口三次握手發(fā)送 SYN 包,會被處于 LAST-ACK狀態(tài)狀態(tài)的被動關(guān)閉方返回一個 RST,三次握手失敗。

    為什么時間是兩個 MSL?

    1 個 MSL 確保四次揮手中主動關(guān)閉方最后的 ACK 報文最終能達(dá)到對端

    1 個 MSL 確保對端沒有收到 ACK 重傳的 FIN 報文可以到達(dá)

    2MS = 去向 ACK 消息最大存活時間(MSL) + 來向 FIN 消息的最大存活時間(MSL)

    在一個非常繁忙的服務(wù)器上,如果有大量 TIME_WAIT 狀態(tài)的連接會怎么樣呢?

    連接表無法復(fù)用

    socket 結(jié)構(gòu)體內(nèi)存占用

    連接表無法復(fù)用  因為處于 TIME_WAIT 的連接會存活 2MSL(60s),意味著相同的TCP 連接四元組(源端口、源 ip、目標(biāo)端口、目標(biāo) ip)在一分鐘之內(nèi)都沒有辦法復(fù)用,通俗一點來講就是“占著茅坑不拉屎”。

    假設(shè)主動斷開的一方是客戶端,對于 web 服務(wù)器而言,目標(biāo)地址、目標(biāo)端口都是固定值(比如本機(jī) ip + 80 端口),客戶端的 IP 也是固定的,那么能變化的就只有端口了,在一臺 Linux 機(jī)器上,端口最多是 65535 個( 2 個字節(jié))。

    如果客戶端與服務(wù)器通信全部使用短連接,不停的創(chuàng)建連接,接著關(guān)閉連接,客戶端機(jī)器會造成大量的 TCP 連接進(jìn)入 TIME_WAIT 狀態(tài)。

    可以來寫一個簡單的 shell 腳本來測試一下,使用 nc 命令連接 redis 發(fā)送 ping 命令以后斷開連接。

    如果在 60s 內(nèi)有超過 65535 次 redis 短連接操作,就會出現(xiàn)端口不夠用的情況,這也是使用 連接池 的一個重要原因。

    針對 TIME_WAIT 持續(xù)時間過長的問題,Linux 新增了幾個相關(guān)的選項,net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_tw_recycle。

    下面我們來說明一下這兩個參數(shù)的用意。 這兩個參數(shù)都依賴于 TCP 頭部的擴(kuò)展選項:timestamp

    TCP 頭部時間戳選項(TCP Timestamps Option,TSopt)

    除了我們之前介紹的 MSS、Window Scale 還有以一個非常重要的選項:時間戳(TCP Timestamps Option,TSopt)

    它由四部分構(gòu)成:類別(kind)、長度(Length)、發(fā)送方時間戳(TS value)、回顯時間戳(TS Echo Reply)。

    時間戳選項類別(kind)的值等于 8,用來與其它類型的選項區(qū)分。長度(length)等于 10。兩個時間戳相關(guān)的選項都是 4 字節(jié)。

    如下圖所示:

    是否使用時間戳選項是在三次握手里面的 SYN 報文里面確定的。

    下面的包是 curl github.com 抓包得到的結(jié)果:

    發(fā)送方發(fā)送數(shù)據(jù)時,將一個發(fā)送時間戳 1734581141 放在發(fā)送方時間戳 TSval 中

    接收方收到數(shù)據(jù)包以后,將收到的時間戳 1734581141 原封不動的返回給發(fā)送方,放在 TSecr 字段中,同時把自己的時間戳 3303928779 放在 TSval 中

    后面的包以此類推

    有幾個需要說明的點:

    1. 時間戳是一個單調(diào)遞增的值,與我們所知的 epoch 時間戳不是一回事。 這個選項不要求兩臺主機(jī)進(jìn)行時鐘同步

    2. timestamps 是一個雙向的選項,如果只要有一方不開啟,雙方都將停用 timestamps。

    比如下面是curl www.baidu.com得到的包

    可以看到客戶端發(fā)起 SYN 包時帶上了自己的TSval,服務(wù)器回復(fù)的SYN+ACK 包沒有TSval和TSecr,從此之后的包都沒有帶上時間戳選項了。

    有了這個選項,我們來看一下 tcp_tw_reuse 選項。

    緩解緊張的端口資源,一個可行的方法是重用“浪費”的處于 TIME_WAIT 狀態(tài)的連接,當(dāng)開啟 net.ipv4.tcp_tw_reuse 選項時,處于 TIME_WAIT 狀態(tài)的連接可以被重用。

    下面把主動關(guān)閉方記為 A, 被動關(guān)閉方記為 B,它的原理是:

    如果主動關(guān)閉方 A 收到的包時間戳比當(dāng)前存儲的時間戳小,說明是一個迷路的舊連接的包,直接丟棄掉

    如果因為 ACK 包丟失導(dǎo)致被動關(guān)閉方還處于LAST-ACK狀態(tài),并且會持續(xù)重傳 FIN+ACK。這時 A 發(fā)送SYN 包想三次握手建立連接,此時 A 處于SYN-SENT階段。 當(dāng)收到 B 的 FIN 包時會回以一個 RST 包給 B,B 這端的連接會進(jìn)入 CLOSED 狀態(tài),A 因為沒有收到 SYN 包的 ACK,會重傳 SYN,后面就一切順利了。

    tcp_tw_recyle 是一個比 tcp_tw_reuse 更激進(jìn)的方案, 系統(tǒng)會緩存每臺主機(jī)(即 IP)連接過來的最新的時間戳。

    對于新來的連接,如果發(fā)現(xiàn) SYN 包中帶的時間戳與之前記錄的來自同一主機(jī)的同一連接的分組所攜帶的時間戳相比更舊,則直接丟棄;如果更新則接受復(fù)用 TIME-WAIT 連接。

    這種機(jī)制在客戶端與服務(wù)端一對一的情況下沒有問題,如果經(jīng)過了 NAT 或者負(fù)載均衡,問題就很嚴(yán)重了。

    什么是 NAT呢?

    NAT(Network Address Translator)的出現(xiàn)是為了緩解 IP 地址耗盡的臨時方案,IPv4 的地址是 32 位,全部利用最 多只能提 42.9 億個地址,去掉保留地址、組播地址等剩下的只有 30 多億,互聯(lián)網(wǎng)主機(jī)數(shù)量呈指數(shù)級的增長,如果給每個設(shè)備都分配一個唯一的 IP 地址,那根本不夠。于是 1994 年推出的 NAT 規(guī)范,NAT 設(shè)備負(fù)責(zé)維護(hù)局域網(wǎng)私有 IP 地址和端口到外網(wǎng) IP 和端口的映射規(guī)則。

    它有兩個明顯的優(yōu)點:

    出口 IP 共享:通過一個公網(wǎng)地址可以讓許多機(jī)器連上網(wǎng)絡(luò),解決 IP 地址不夠用的問題

    安全隱私防護(hù):實際的機(jī)器可以隱藏自己真實的 IP 地址 當(dāng)然也有明顯的弊端:NAT 會對包進(jìn)行修改,有些協(xié)議無法通過 NAT。

    當(dāng) tcp_tw_recycle 遇上 NAT 時,因為客戶端出口 IP 都一樣,會導(dǎo)致服務(wù)端看起來都在跟同一個 host 打交道。

    不同客戶端攜帶的 timestamp 只跟自己相關(guān),如果一個時間戳較大的客戶端 A 通過 NAT 與服務(wù)器建連,時間戳較小的客戶端 B 通過 NAT 發(fā)送的包服務(wù)器認(rèn)為是過期重復(fù)的數(shù)據(jù),直接丟棄,導(dǎo)致 B 無法正常建連和發(fā)數(shù)據(jù)。

    TIME_WAIT 狀態(tài)是最容易造成混淆的一個概念,這個狀態(tài)存在的意義是:

    1. 可靠的實現(xiàn) TCP 全雙工的連接終止(處理最后 ACK 丟失的情況)

    2. 避免當(dāng)前關(guān)閉連接與后續(xù)連接混淆(讓舊連接的包在網(wǎng)絡(luò)中消逝)

    假設(shè) MSL 是 60s,請問系統(tǒng)能夠初始化一個新連接然后主動關(guān)閉的最大速率是多少(忽略1~1024區(qū)間的端口)?

    2MSL = 120s,(65535 - 1024) / 120 = 537.6 次/秒

    每120秒可以初始化(65535-1024 )個

    “時間戳是一個單調(diào)遞增的值,與我們所知的 epoch 時間戳不是一回事” 這個epoch和時間戳分別是什么差異?

    不是一回事,跟時間沒有什么關(guān)系,只是隨著時鐘信號CPU中斷遞增。

    SO_REUSEADDR是針對服務(wù)端的,tcp_tw_reuse和tcp_tw_recyle是針對客戶端的,可以這樣理解嗎?

    SO_REUSEADDR 兩端都可以用,不過服務(wù)端上因為經(jīng)常要固定端口,不設(shè)置,下次重啟就bind 失敗 。

    tcp_tw_reuse和tcp_tw_recyle 也是主要用于繁忙的“服務(wù)端”,“客戶端”和“服務(wù)端”這個說法是在不同的場景下可以互相轉(zhuǎn)換的,服務(wù)端也可以發(fā)起請求充當(dāng)客戶端 。

    深入理解 TCP 協(xié)議:從原理到實戰(zhàn)

    https://juejin.cn/book/6844733788681928712/section/6844733788837117959

    從SO_REUSEADDR選項說起

    https://zhuanlan.zhihu.com/p/31329253

    四、Linux下netstat查看處于TIME_WAIT的socket過多

    在Linux中使用如下的命令查看Linux內(nèi)核中各種狀態(tài)的socket

    在答主電腦中如下所示:

    各個狀態(tài)的socket:

    CLOSED:無連接是活動的或正在進(jìn)行

    LISTEN:服務(wù)器在等待進(jìn)入呼叫

    SYN_RECV:一個連接請求已經(jīng)到達(dá),等待確認(rèn)

    SYN_SENT:應(yīng)用已經(jīng)開始,打開一個連接

    ESTABLISHED:正常數(shù)據(jù)傳輸狀態(tài)

    FIN_WAIT1:應(yīng)用說它已經(jīng)完成

    FIN_WAIT2:另一邊已同意釋放

    ITMED_WAIT:等待所有分組死掉

    CLOSING:兩邊同時嘗試關(guān)閉

    TIME_WAIT:另一邊已初始化一個釋放

    LAST_ACK:等待所有分組死掉

    如果目前內(nèi)核中存在大量處于TIME_WAIT狀態(tài)的socket,那么說明這些socket還沒有被釋放掉,它們還占用著資源,這樣就有可能導(dǎo)致操作系統(tǒng)的負(fù)載過高,怎么解決這個問題呢?

    通過調(diào)整內(nèi)核參數(shù)來解決:

    增加如下內(nèi)容:

    執(zhí)行下面命令讓參數(shù)生效:

    以上就是關(guān)于出現(xiàn)大量time_wait狀態(tài)相關(guān)問題的回答。希望能幫到你,如有更多相關(guān)問題,您也可以聯(lián)系我們的客服進(jìn)行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。


    推薦閱讀:

    共享單車出現(xiàn)的原因(共享單車出現(xiàn)的原因多方面)

    團(tuán)隊中容易出現(xiàn)的問題(團(tuán)隊中容易出現(xiàn)的問題有哪些)

    ChatGPT老出現(xiàn)不可用(chnct不可用)

    賽事主題活動策劃方案(賽事主題活動策劃方案怎么寫)

    2022年世界各國GDP總量(202o年世界各國gdp)