在上篇文章 每個後端都應該瞭解的 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 只能被安裝在類 Unix 系統上,所以我們需要一個 Linux 或者 MacOS 環境。Windows 10 安裝需要開啟自帶的 Ubuntu 子系統。
對於 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
Mac 系統也可以通過先編譯的方式來安裝,但是更推薦使用 brew 的方式來安裝, 步驟如下:
brew install wrk
;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 的組態檔做一些修改,如下:
# 設定工作程序數量
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 <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 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頻寬,測試結果大家理性看待,歡迎大家自己測試。
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 的引數會影響壓測的結果,因此我們需要根據實際情況選擇合適的引數。一般來說,我們可以參考以下步驟:
wrk 在壓測過程中可能會出現一些錯誤,例如連線超時、連線拒絕、連線重置等。這些錯誤可能是由於目標伺服器的效能不足、網路環境不穩定、防火牆限制等原因造成的。我們可以嘗試以下方法來解決或減少錯誤:
wrk 在對 OpenResty
程式的壓測過程中,不失所望表現出了強大壓測效能。希望通過本篇文章能讓大家對 wrk 效能測試工具有一個較為全面的認識。
關注公眾號【waynblog】每週分享技術乾貨、開源專案、實戰經驗、國外優質文章翻譯等,您的關注將是我的更新動力!