OpenResty入門之壓測篇:壓測工具界的 “悍馬” wrk 審核中

来源:https://www.cnblogs.com/waynaqua/archive/2023/10/20/17777496.html
-Advertisement-
Play Games

在上篇文章 每個後端都應該瞭解的 OpenResty 入門以及網關安全實戰 中,我向大家介紹了 OpenResty 的入門使用是 WAF 防禦實戰,這篇文章將給大家繼續介紹 OpenResty 入門之性能測試 篇。 性能測試是軟體開發中不可或缺的一環,它可以幫助我們評估系統的性能、穩定性、可擴展性等 ...


在上篇文章 每個後端都應該瞭解的 OpenResty 入門以及網關安全實戰 中,我向大家介紹了 OpenResty 的入門使用是 WAF 防禦實戰,這篇文章將給大家繼續介紹 OpenResty 入門之性能測試 篇。

性能測試是軟體開發中不可或缺的一環,它可以幫助我們評估系統的性能、穩定性、可擴展性等指標,為優化和改進提供依據。但是,性能測試也是最容易失準的一種測試,因為它受到很多因素的影響,例如網路環境、伺服器配置、壓測工具、壓測場景等。如果我們選擇了不合適的壓測工具或者沒有設計好壓測場景,那麼我們得到的結果可能會與實際情況相差甚遠,甚至導致錯誤的判斷和決策。

俗話說工欲善其事必先利其器,那麼如何選擇一款合適的壓測工具呢?首先 OpenResty 是 fork 自 Nginx 開發,基於 Nginx 原有的強悍性能(協程 + IO 多路復用 Epoll),其性能就不會差。所以我們需要的是一款自身性能足夠強悍,可以最大程度榨乾 OpenResty 程式性能、服務端 cpu 資源的壓測工具。

這裡給大家介紹一款壓測工具界的“悍馬” —— wrk。wrk 是一款針對 HTTP 協議的基準測試工具,它能夠在單機多核 CPU 的條件下,使用系統自帶的高性能 I/O 機制,如 epoll,kqueue 等,通過多線程和事件模式,對目標機器產生大量的負載。wrk 支持 Lua 腳本來創建複雜的測試場景(這一點與 OpenResty 支持 Lua 腳本相同),也可以輸出詳細的響應時間統計信息。wrk 的優點有以下幾點:

  • 高性能:wrk 可以利用多核 CPU 的並行計算能力,同時使用多個線程和連接來發送請求,並且使用高效的 I/O 模型來處理響應。這樣,wrk 可以在單機上產生高達數十萬甚至數百萬級別的 QPS(每秒請求數),遠超過其他常見的壓測工具,如 ab、siege、jmeter 等。
  • 靈活:wrk 支持使用 Lua 腳本來定製壓測場景,例如自定義 HTTP 方法、動態生成請求參數、修改請求頭等。這樣,我們可以模擬各種複雜和真實的用戶行為和業務邏輯,使得壓測結果更加貼近實際情況。
  • 簡潔:wrk 的安裝和使用都非常簡單,只需要幾條命令就可以完成。wrk 的輸出也非常清晰和直觀,可以顯示每個線程和總體的響應時間和每秒請求數,並且可以列印出響應時間的分佈情況,方便我們分析系統的性能瓶頸。

wrk 的安裝

wrk 只能被安裝在類 Unix 系統上,所以我們需要一個 Linux 或者 MacOS 環境。Windows 10 安裝需要開啟自帶的 Ubuntu 子系統。

Linux 安裝

對於 Ubuntu/Debian 系統,可以通過以下命令安裝 wrk:

sudo apt-get install build-essential libssl-dev git -y
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 將可執行文件移動到 /usr/local/bin 位置
sudo cp wrk /usr/local/bin

對於 CentOS / RedHat / Fedora 系統,可以通過以下命令安裝 wrk:

sudo yum groupinstall 'Development Tools'
sudo yum install -y openssl-devel git
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 將可執行文件移動到 /usr/local/bin 位置
sudo cp wrk /usr/local/bin

MacOS 安裝

Mac 系統也可以通過先編譯的方式來安裝,但是更推薦使用 brew 的方式來安裝, 步驟如下:

  • 安裝 Homebrew,安裝方式參考官網 https://brew.sh (也就一行命令的事);
  • 安裝 wrk: brew install wrk;

Windows 10 安裝

Windown 10 需要在 Windows 功能 里勾選 適用於 Linux 的 Windows 子系統, 然後通過 bash 命令切換到 Ubuntu 子系統。接下來,參考 Linux 安裝 的操作步驟,安裝 wrk。

壓測前準備

在開始壓測前,我們還需要對測試環境進行一番調整,已配合壓測工具 wrk 榨乾 OpenResty 程式的性能。

單進程最大文件數

Linux 系統預設對每個進程能夠打開的文件數有一個限制,通常是 1024 個。這個限制會影響到伺服器能夠同時處理的連接數,因此需要增加這個限制。增加的方法是修改 /etc/security/limits.conf 文件,添加如下內容:

* soft nofile 65535
* hard nofile 65535

其中 * 號表示修改所有用戶的限制,soft 或 hard 指定要修改軟限制還是硬限制,65536 則指定了想要修改的新的限制值,即最大打開文件數(請註意軟限制值要小於或等於硬限制)。修改完後保存文件。

這樣就可以將所有用戶的單進程最大打開文件數限制設為 65535 個。如果還不夠,可以繼續增大這個值,但要註意不要超過系統級的最大打開文件數限制,可以通過 cat /proc/sys/fs/file-max 命令查看這個限制。

最大打開文件數

查看 Linux 系統級的最大打開文件數限制,使用如下命令:

[root@VM-16-5-centos ~]# cat /proc/sys/fs/file-nr
2112	0	369508

這裡的最後一個數字,就是最大打開文件數。如果你的機器中這個數字比較小,那就需要修改 /etc/sysctl.conf 文件來增大:

fs.file-max = 1020000
net.ipv4.ip_conntrack_max = 1020000
net.ipv4.netfilter.ip_conntrack_max = 1020000

修改完以後,還需要重啟系統服務來生效:

sysctl -p /etc/sysctl.conf

Nginx 工作進程數量以及連接數

最後,我們還需要對 Nginx 的配置文件做一些修改,如下:

# 配置工作進程數量
worker_processes  1;

...

events {
    # 單個工作進程處理連接數量
    worker_connections  1024;
}

預設情況下 Nginx 有 master 和 worker 兩種進程,master 進程用於管理 worker 進程,worker 進程用於處理外部請求也就是對外提供服務。

worker_processes 1 的配置說明工作進程數預設為 1。在多核機器上我們可以設置為伺服器 CPU 的核數以提升 Nginx 的連接處理數。

worker_connections 1024 的配置說明單個進程能處理的連接數量是 1024,在大壓力場景下,我們可以提升這個值,改為 10240。

最後,優化的 Nginx 配置文件如下:

# 根據cpu核數自動設置工作進程數量
worker_processes  auto;

...

events {
    # 單個工作進程處理連接數量
    worker_connections  10240;
}

wrk 的使用

wrk 的基本用法是:

wrk <options> <url>

其中,<options> 是一些可選的參數,用來控制壓測的配置,<url> 是要壓測的目標網址。

常用參數

wrk 支持以下常用參數:

  • -c, --connections <N>:指定要保持打開的連接數;
  • -d, --duration <T>:指定壓測的持續時間;
  • -t, --threads <N>:指定要使用的線程數;
  • -s, --script <S>:指定要載入的 Lua 腳本文件;
  • -H, --header <H>:指定要添加到請求中的 HTTP 頭;
  • --latency:指定要列印響應時間統計信息;
  • --timeout <T>:指定套接字/請求超時時間;

其中,數字參數可以使用 SI 單位(1k, 1M, 1G),時間參數可以使用時間單位(2s, 2m, 2h)。

壓測示例

現在我們要對 OpenResty 程式的 hello 介面進行壓測,我們可以使用以下命令:

wrk -c 100 -d 30s -t 4 --latency http://121.4.xxx.xx/hello

這條命令表示,利用 wrk 發起壓力測試,連接數為 100,線程數為 4,持續 10 秒,並列印響應時間統計信息。

運行後,我們可以看到以下輸出:

Running 30s test @ http://121.4.xxx.xx/hello
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    60.74ms   94.62ms   1.82s    88.81%
    Req/Sec   710.91    118.29     1.02k    69.08%
  Latency Distribution
     50%   26.22ms
     75%   32.99ms
     90%  176.28ms
     99%  475.41ms
  84967 requests in 30.02s, 15.40MB read
  Socket errors: connect 0, read 0, write 0, timeout 2
Requests/sec:   2829.91
Transfer/sec:    525.08KB

我們可以從輸出中看到以下信息:

  • 壓測的配置和目標網址,
Running 30s test @ http://121.4.xxx.xx/hello
  4 threads and 100 connections
  • 每個線程的平均、標準差、最大和正負一個標準差占比的響應時間(Latency),
  Latency    60.74ms   94.62ms   1.82s    88.81%

這個數據和 QPS 一樣重要,表示系統的響應速度,這個值越小越好。

  • 響應時間的分佈情況:即有多少比例的請求在某個時間內完成,延時的分佈百分比詳細列印也就是下麵展示信息,
  Latency Distribution
     50%   26.22ms
     75%   32.99ms
     90%  176.28ms
     99%  475.41ms
  • 總的請求數,
Requests/sec:   2829.91

這個數據表示服務端每秒鐘處理了多少請求,這個值越大越好。

從這些信息中,我們可以看出 OpenResty 程式的性能還是很不錯的,響應時間都在幾毫秒級別,QPS 也很高。

鑒於我的 OpenResty 伺服器配置只有 2核4g記憶體5MB帶寬,測試結果大家理性看待,歡迎大家自己測試。

Lua 腳本

wrk 支持使用 Lua 腳本來定製壓測場景,例如自定義 HTTP 方法、動態生成請求參數、修改請求頭等。這樣,我們可以模擬各種複雜和真實的用戶行為和業務邏輯,使得壓測結果更加貼近實際情況。wrk 的源碼中提供了一些示例腳本,可以參考 https://github.com/wg/wrk/tree/master/scripts。

要使用 Lua 腳本,我們需要在命令行中指定 -s 參數,並給出腳本文件的路徑。例如我們可以使用 post.lua 腳本來發送 POST 請求:

wrk -c 100 -d 10s -t 4 -s post.lua http://121.4.xxx.xx/hello

其中,post.lua 的內容如下:

wrk.method = "POST"
wrk.body   = "name=tom"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

這樣,我們就可以模擬發送 POST 請求攜帶表單數據的場景。

一些常見問題

如何選擇合適的參數?

wrk 的參數會影響壓測的結果,因此我們需要根據實際情況選擇合適的參數。一般來說,我們可以參考以下步驟:

  • 先使用單線程不斷增加連接數,直到 QPS(每秒請求數)保持穩定或響應時間超過業務要求限制。在當前數值取得單線程最優連接數。
  • 單個連接線程數保持不變,不斷增加線程數(建議到 CPU 核心數為止即可),直到整體出現 QPS 水平。
  • 如果 QPS 沒有出現隨著線程數增長則是目標伺服器性能已經達到瓶頸,wrk 單線程即可壓測出目標機器最優 QPS 值。
  • 如果 QPS 隨著線程數增長則是 wrk 本機性能達到瓶頸,需要增加 wrk 機器數或者更換更高性能的 wrk 機器。

如何解決壓測過程中出現的錯誤?

wrk 在壓測過程中可能會出現一些錯誤,例如連接超時、連接拒絕、連接重置等。這些錯誤可能是由於目標伺服器的性能不足、網路環境不穩定、防火牆限制等原因造成的。我們可以嘗試以下方法來解決或減少錯誤:

  • 調整 wrk 的參數,例如減少連接數、增加超時時間等;
  • 檢查目標伺服器的資源使用情況,例如 CPU、記憶體、磁碟、網路等,優化伺服器的配置或擴容伺服器;
  • 檢查網路環境,例如帶寬、延遲、丟包等,優化網路設備或更換網路線路;
  • 檢查防火牆設置,例如埠開放、流量限制等,放開 wrk 的訪問許可權或關閉防火牆;

總結

wrk 在對 OpenResty 程式的壓測過程中,不失所望表現出了強大壓測性能。希望通過本篇文章能讓大家對 wrk 性能測試工具有一個較為全面的認識。

關註公眾號【waynblog】每周分享技術乾貨、開源項目、實戰經驗、國外優質文章翻譯等,您的關註將是我的更新動力!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • React採用on+事件名的方式來綁定一個事件,註意,這裡和原生的事件是有區別的,原生的事件全是小寫 onclick , React里的事件是駝峰 onClick ,React的事件並不是原生事件,而是合成事件。 事件回調的幾種寫法 1.直接在組件內定義一個非箭頭函數的方法,然後在render里直接 ...
  • 本文分享自華為雲社區《從0到1實現 OpenTiny 組件庫跨框架技術》,作者:華為雲社區精選 。 在華為雲《DTSE Tech Talk》技術直播第44期《0基礎玩轉 OpenTiny 跨框架組件庫,實現一站式前端進階》中,華為雲前端開發 DTSE 技術佈道師莫春輝老師在本期直播中與開發者一起交流 ...
  • 接上一節:從零用VitePress搭建博客教程(3) - VitePress頁腳、標題logo、最後更新時間等相關細節配置 六、首頁樣式修改 有時候覺得自帶的樣式不好看,想自定義,首先我們在docs/.vitePress新建一個theme文件夾,用來存放自定義佈局和主題修改的相關文件,如下所示 th ...
  • 目錄 1. HTTP協議 2. HttpServlet 內容 HTTP 什麼是HTTP協議 HTTP 協議一般指 HTTP(超文本傳輸協議)。超文本傳輸協議(英語:HyperText Transfer Protocol,縮寫:HTTP)是一種用於分散式、協作式和超媒體信息系統的應用層協議,是網際網路上 ...
  • Python支持來自數學的通常邏輯條件: 等於:a == b 不等於:a != b 小於:a < b 小於或等於:a <= b 大於:a > b 大於或等於:a >= b 這些條件可以以多種方式使用,最常見的是在"if語句"和迴圈中使用。 if語句是使用if關鍵字編寫的。 示例,if語句: a = ...
  • 知識總覽 2.3.1 單鏈表的定義 知識總覽 單鏈表定義 #include<stdio.h> #include<string.h> #include<stdlib.h> struct LNode{ int data; struct LNode *next; }; int main(){ struct ...
  • dpkt項目是一個`Python`模塊,主要用於對網路數據包進行解析和操作。它可以處理多種協議,例如`TCP`、`UDP`、`IP`等,並提供了一些常用的網路操作功能,例如計算校驗和、解析`DNS`數據包等。由於其簡單易用的特性,`dpkt`被廣泛應用於網路安全領域,例如流量分析、漏洞利用、入侵檢測... ...
  • 一、掃雷游戲分析 關鍵步驟:兩個二維數組的大小為11*11,但實際上操作的只有中心的9*9的棋盤,創建另外兩行的原因是方便統計一個坐標周圍3*3的雷的個數1.創建兩個二維數組一個存放佈置好的雷(1號),另外一個存放空的棋盤(2號)2.選手選出來的坐標傳到1號棋盤上對坐標進行分析如果是雷就返回被炸死了 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...