對 wrk 延遲分布不準確的分析
來自專欄第二層思考1 人贊了文章
題圖:Photo by Snapwire from Pexels
wrk 是一個非常棒的 HTTP 壓力測試工具,構建在 Redis、NGINX、Node.js 和 LuaJIT 這幾個開源項目的基礎之上,充分利用了他們在事件驅動、HTTP 解析、高性能和靈活性方面的優點,並且可以自己寫 Lua 腳本來生成測試請求。
雖然 wrk 沒有測試案例,並且作者大概一年現身一次來合併代碼,但這些並不妨礙我們把 wrk 作為性能測試和 fuzz 測試的首選工具。如果你還在使用多線程的 ab,那麼非常值得嘗試下 wrk。
下面是 wrk 結果中的延時分布統計部分:
Latency Distribution 50% 1.20ms 75% 595.78ms 90% 899.11ms 99% 1.00s
這個示例是指,50% 的請求在 1.2ms 內完成,90% 的請求在 899 ms 內完成,99% 的請求在 1s 內完成。
我們在使用 wrk 壓力測試自己產品的時候,發現 wrk 統計的延時結果中,大部分請求都是幾毫秒內完成,但有一小部分請求的延時會超過 100 毫秒。 對於用 OpenResty 構建的系統,出現這麼大的延時是不太科學的事情。
雖然這個問題最終解決方法非常簡單,但具體的分析和定位有些曲折,花了好幾天的時間。最終的解決方法並不重要,過程和思考問題的方式才是值得關注的。
遇到延遲問題,我們的第一反應是代碼或者系統某個地方有阻塞。 由於系統比較複雜,所以我們祭出了火焰圖。
沒有現成的 systemtap 腳本來分析這類問題,所以花了點時間寫腳本。但調整了幾次 systemtap 腳本,都沒有捕獲到明顯的延時,這個和 wrk 的結果明顯不符。我們猜測這個腳本可能不夠完善,可能遺漏了某些函數沒有 hook 住。但同時也對 wrk 的結果是否正確產生了懷疑。
我們調轉方向,先來定位到底是 wrk 統計錯了,還是確實是 server 的問題。我們在 wrk 所在的伺服器上,把壓測期間的包都 dump 出來,按照耗時進行排序,驚奇的發現結果和 wrk 的延時統計大相徑庭,沒有發現超過 100 毫秒的請求。重複了幾次以上測試,結果都一致。
這下目標就很明確了,只要把 wrk 關於延遲統計的代碼捋順就可以了。最擔心的就是 wrk 內部統計時候有 bug,這就不好修復了,畢竟是一個沒有任何測試案例的項目:(
我們仔細過了一遍 wrk 的統計邏輯,並在開始和結束的地方加了日誌,發現關於延時的統計都是正確的,這也讓我們鬆了一口氣。但是在列印最終結果之前,有一段統計數據校正
的代碼:
if (complete / cfg.connections > 0) { int64_t interval = runtime_us / (complete / cfg.connections); stats_correct(statistics.latency, interval); }
按照這個 if 判斷,只要有壓測數據產生,就會進行校正。有興趣的同學,可以去看看 stats_correct
函數的代碼,只有 10 行,我看了幾遍也沒看懂。
再去查代碼的提交記錄,說不定有什麼收穫,但只有下面這一行,又沒看懂:
remove calibration & improve CO correction
吐槽下,如果提交記錄稍微詳細一點兒,不用縮寫,或者加個代碼注釋,就能省不少事兒。
問題查到這裡,已經可以證實不是產品的問題,而且解決方法已經有了,就是注釋掉上面這段校正的代碼。但 wrk 作者特意加上肯定是有原因的,不明白這個原因始終是個隱患。自然的,要開一個 issue 來請教下作者,一年現身一次的 wg 在 15 天后給了答覆,原來上面 commit info 裡面的縮寫 CO
是指 Coordinated Omission
,並且給了一篇專門講這個問題的文章,感興趣的同學可以用這個關鍵字自行搜索。
簡單的說,Coordinated Omission
是指在做壓力測試的時候,只統計發送和收到回復之間的時間是不夠的,這個是指服務時間
,會遺漏掉很多潛在的問題,還需要把測試請求的等待時間也計算在內,才算是用戶關心的響應時間
。
提出 CO 這個問題的 Gil Tene,還對 wrk 做了修改,專門解決 CO 的問題: https://github.com/giltene/wrk2,在這個項目的 README 裡面也有一些對此的解釋,有興趣的可以看看,這裡就不多提及了。
對於我們自己的產品來說,代碼中肯定不會有任何阻塞,在做壓力測試的時候,是會把 CPU 跑滿。即使出現阻塞,也是有火焰圖來採樣分析的。所以 wrk 這裡針對 Coordinated Omission 做的簡單粗暴的校正,反而會產生誤導。
歷史文章推薦:
如何構建自己的投資體系?(上)
一個黑客的自述:我曾吹響進攻的號角
推薦閱讀: