壓測場景下的 TIME WAIT 處理

2021-10-19 07:31:15 字數 3382 閱讀 9490

簡介: 壓測場景下的 time_wait 處理

某專有雲專案具備壓測場景,在windows的壓測機上用 loadrunner 進行業務的壓力測試,壓測執行一段時間後出現大量埠無法分配的報錯。

其實通過問題描述,以及 windows的報錯資訊基本確定是壓測機的問題。但可能原因較多,一直未能達成一致。所以,趁機分析了客戶端的壓測機成為壓測瓶頸的可能,除了cpu、網路、 i/o 等機器效能引數外,仍需考慮網路協議引入的資源短缺問題。

注:以下內容的目的是理清tcp協議中比較模糊的內容,對協議比較熟悉的可以忽略。

圖1. tcp狀態轉換圖

本文僅針對 tw 在tcp協議中的作用進行討論,不涉及整體協議的分析。四次揮手後的time_wait 狀態,後續將以tw縮寫替代。

首先,主要作用是保證tcp連線關閉的可靠性。

考慮下在四次揮手過程中,如果主動關閉方傳送的last_ack丟失,那麼被動關閉方會重傳fin。此時,如果主動關閉方對應的tcp endpoint沒有進入tw狀態而是直接在核心中清理了,根據協議,主動關閉方會認為自己沒有開啟過這個埠,而以rst響應被動關閉方重傳的fin。最終該行為導致被動關閉方認為連線異常關閉,在業務上可能會收到異常報錯等情況。

其次,tw狀態同時也能避免相同的tcp埠收到在網路上前乙個連線的重複資料報。

理論上,資料報在網路上過期時間對應即msl(maximal segment lifetime),隨著作業系統的不斷發展,也有例外情況,這部分搜尋paws應該可以看到不少類似的文章說明。

再次,埠進入 tw 狀態 同時也避免了被作業系統快速重複使用的可能。

當一台主機作業系統主動關閉tcp endpoint(socket)時,該tcp endpoint進入tw狀態。以windows為例,windows核心會對 tcp endpoint 資料結構進行相應清理,然後放入額外的 tw queue 中,設定2msl 的定時器,等待定時器超時後呼叫對應的釋放**。linux上的實現也是類似。

目前較多的說法是"tcp連線"進入tw ,但我們可能需要理解 "連線" 其實是抽象的概念。實際上"連線"在邏輯上存在,因為客戶端和伺服器端以及中間可能涉及的4層裝置同時為一次傳輸建立了關聯的tcp資源(endpoint,或者 session)。準確理解tw狀態,即tcp endpointtw進入tw狀態。

作為連線雙方,客戶端和伺服器端的tcp endpoint都可能進入 tw 狀態(極端情況下,可能雙方同時進入 tw 狀態)。

tw 是標準的一部分,不代表tcp埠或者連線狀態異常。(這個概念很重要,避免陷入某些不必要的陷阱。)

close_wait 儘管也是標準的一部分,但它的出現預示著本端的 tcp endpoint 處於半關閉狀態,原因常常是應用程式沒有呼叫 socket 相關的 close 或者 shutdown。可能的原因是應用程式仍有未傳送完成的資料,該情況下close_wait 最終還是會消失的。 具體描述這部分,長期有 close_wait 狀態的埠緩慢累積,這種情況是需要引起注意的,累積到一定程度,埠資源就不夠了。

針對前面的 tcp endpoint 這個詞語,可能很多人不太了解,這邊也簡單說明下:

在windows 2008 r2之前,socket是使用者態(user mode) 的概念,大多數windows socket應用程式基本都基於winsock開發,由中間層afd.sys 驅動翻譯成核心 tcpip.sys 協議棧驅動 所能接受的tcp endpoint資料結構。在2008 r2之後,微軟為了方便核心的網路程式設計,在windows kernel中提供wsk,即winsock在核心的實現。文中提到的tcp endpoint是在windows核心中由tcpip.sys驅動檔案實現的tcp資料結構,也對應linux上的socket。該文簡單以 endpoint 代指核心的"socket"。

對於linux,優化手段已經進行了很多討論了,以centos為例,

在timestamps啟用的情況下,配置 tcp_tw_reuse 和tcp_tw_recycle。

針對客戶端,連線請求發起方。

net.ipv4.tcp_timestamps = 1

net.ipv4.tcp_tw_reuse = 1

配置 max_tw_buckets,連線請求發起方接收方通用,但需要注意這個選項本身有違 tw 設計的初衷。

net.ipv4.tcp_max_tw_buckets = 5000

配置 ip_local_port_range,連線請求發起方。

net.ipv4.ip_local_port_range = 5000 65535

針對windows ,資料較少,這邊借之前的工作經驗,總結如下:

windows vista / windows server 2008 之前的作業系統,登錄檔

windows 7 / windows server 2008 r2 及其之後的版本

windows server 2012 and earlier: 30-300 (decimal)

windows 8 and earlier: 30-300 (decimal)

windows server 2012 r2 and later: 2-300 (decimal)

windows 8.1 and later: 2-300 (decimal)

注:新連線請求的seq序列號》tw狀態的endpoint記錄的seq序列號。

此時,核心會認為該 syn 請求合法。 這裡,這個tw 狀態的 tcp endpoint 一定是在服務端(通過socket accept 開啟的 服務埠)。(為了這個能力,windows 的 rfc 1323 選項必須開啟,內容可以自行搜尋。)

埠無法分配有兩種可能:

理解了 tw 的形成原因,相應的解決方案也就比較清楚了。

降低應用程式建立埠的速度。考慮連線持續時間和tw超時時間,計算相對合理的連線建立速度。不過,物理機作業系統、cpu/記憶體、網路io等均可能影響連線狀態,精確計算很難;同時,就應用程式而言,降低埠建立速度需要額外的邏輯,可能性不大。

在這個壓測場景下,通過增加機器的方式來變相減少埠的需求。壓測一般考慮某個固定閾值下整體系統的響應情況。在壓力固定的情況下,可以通過分散壓力的方式來減少埠資源的占用。

改變連線的行為,使用持久連線(注:非http的長連線),例如針對500個併發,僅建立 500 個連線。好處顯而易見,但壞處也很明顯,持久連線不大符合使用者真實行為,壓測結果可能失真。同時,該方法需要應用程式上的支援。

圖3:loadrunner abrupt配置選項說明

場景壓測設計1

1.執行緒組就是幾個使用者去跑步 2.ramp up period 就是在多少時間內跑完 3.迴圈次數 就是每個使用者都跑幾次 4.聚合報告是計算總數的,就是執行緒組迴圈的累加 執行緒組的迴圈次數,是下面所有的請求都要迴圈的次數 5.模組控制器,只能控制到模組的維度 不涉及模組下面的了 6.模組控制...

Jmeter效能測試之壓測場景介紹

1.1基準測試 基準測試是用單個使用者對需要壓測的交易壓測5 10分鐘,初步了解下該交易的響應時間和tps,一般此過程不會出現問題。1.2單場景負載測試 單場景負載測試是對需要壓測的交易使用80使用者併發,壓測10分鐘左右,考查單個交易的負載情況。這個場景容易測試出來響應時間慢或者伺服器資源利用率高...

(jmeter筆記)模擬使用者各種場景壓測

外掛程式 standard set 1.jp gc ultimate thread group 波浪式壓測,最終執行緒組 start threads count 設定啟用併發數 initial delay,sec 設定延遲時間,延遲多少秒開始 startup time,sec 設定啟動時間,持續多少...