簡介
ab命令會創建多個並發訪問線程,模擬多個訪問者同時對某一URL地址進行訪問。它的測試目標是基於URL的;
# 1.ab每次只能測試一個URL,適合做重復壓力測試
# 2.參數很多,可以支持添加cookie,啟用keeplive
# 3.可以將測試結果導入文件
# 4.設置顯示信息的詳細程度
綜合來說,適合單個URL的測試,可以支持更多方式去測試,比如使用cookie模仿用戶提交表單來測試數據庫,但ab是單線程的,不適合測性能高的服務器;
安裝ab
需要安裝httpd-tools
yum -y install httpd-tools
使用案例
Example1
ab -c 1000 -n 10000 http://192.168.2.38/
# -c指定1000並發,-n指定總10000次,相當於1000個人訪問10次。
# -k 是否開啟長連接
Server Software: nginx/1.8.1 #服務器信息和版本
Server Hostname: 192.168.2.38 #服務器的域名
Server Port: 80 #端口
Document Path: / #訪問的路徑
Document Length: 612 bytes #文檔的大小為 612 bytes(此為http響應的正文長度)
Concurrency Level: 1000 #並發請求數
Time taken for tests: 0.287 seconds #整個測試持續的時間,默認秒
Complete requests: 1000 #完成的請求數
Failed requests: 0 #失敗的請求書
Write errors: 0 #網絡連接寫入錯誤數
Total transferred: 844000 bytes #傳輸的總數據量
HTML transferred: 612000 bytes #傳輸的HTML內容傳輸量
Requests per second: 3485.11 [#/sec] (mean) #平均每秒請求數
Time per request: 286.935 [ms] (mean) #所有用戶都請求一次的平均時間
Time per request: 0.287 [ms] (mean, across all concurrent requests) #單個用戶請求一次的時間
Transfer rate: 2872.49 [Kbytes/sec] received #傳輸速率
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 84 4.1 84 94
Processing: 86 99 6.6 100 109
Waiting: 0 83 16.2 84 108
Total: 95 183 7.4 182 195
#所有服務請求的百分比占用時間,這里50%的請求用時182ms,一般看90%的部分
Percentage of the requests served within a certain time (ms)
50% 182
66% 188
75% 191
80% 192
90% 193
95% 194
98% 194
99% 194
100% 195 (longest request)
可能會報錯
apr_socket_recv: Connection reset by peer (104)
Total of 29969 requests completed
連接被重置,bingyi了以下,apr_socket_recv這個是操作系統內核的一個參數,在高並發的情況下,內核會認為系統受到了SYN flood攻擊,會發送cookies(possible SYN flooding on port 80. Sending cookies),這樣會減慢影響請求的速度,所以在應用服務武器上設置下這個參數為0禁用系統保護就可以進行大並發測試了;
然后就可以超過1000個並發測試了,但是ab只支持
# vim /etc/sysctl.conf
net.ipv4.tcp_syncookies = 0
# sysctl -p
接下來是每秒訪問,因為ab不支持每秒訪問多少,所以寫一個腳本
#!/bin/bash
#當下是運行60秒,每秒1000並發,可以觀察服務器負載
for i in `seq 1 60`
do
ab -c 1000 -n 1000 http://192.168.2.38/ &
sleep 1
done
Example2(使用cookie模擬多用戶)
1.使用cookie來模擬多個用戶訪問
先用賬戶和密碼登錄后,用開發者工具找到標識這個會話的Cookie值(Session ID)記下來
# 一個
ab -n 100 -C key=value http://test.com/
# 多個賬號
ab -n 100 -H “Cookie: Key1=Value1; Key2=Value2” http://test.com/
具體參數
-n 即requests,用於指定壓力測試總共的執行次數。
-c 即concurrency,用於指定壓力測試的並發數。
-t 即timelimit,等待響應的最大時間(單位:秒)。
-b 即windowsize,TCP發送/接收的緩沖大小(單位:字節)。
-p 即postfile,發送POST請求時需要上傳的文件,此外還必須設置-T參數。
-u 即putfile,發送PUT請求時需要上傳的文件,此外還必須設置-T參數。
-T 即content-type,用於設置Content-Type請求頭信息,例如:application/x-www-form
-urlencoded,默認值為text/plain。
-v 即verbosity,指定打印幫助信息的冗余級別。
-w 以HTML表格形式打印結果。
-i 使用HEAD請求代替GET請求。
-x 插入字符串作為table標簽的屬性。
-y 插入字符串作為tr標簽的屬性。
-z 插入字符串作為td標簽的屬性。
-C 添加cookie信息,例如:"Apache=1234"(可以重復該參數選項以添加多個)。
-H 添加任意的請求頭,例如:"Accept-Encoding: gzip",請求頭將會添加在現有的多個請求頭之后(可以重復該參數選項以添加多個)。
-A 添加一個基本的網絡認證信息,用戶名和密碼之間用英文冒號隔開。
-P 添加一個基本的代理認證信息,用戶名和密碼之間用英文冒號隔開。
-X 指定使用的代理服務器和端口號,例如:"126.10.10.3:88"。
-V 打印版本號並退出。
-k 使用HTTP的KeepAlive特性。
-k 使用HTTP的KeepAlive特性。
-d 不顯示百分比。
-S 不顯示預估和警告信息。
-g 輸出結果信息到gnuplot格式的文件中。
-e 輸出結果信息到CSV格式的文件中。
-r 指定接收到錯誤信息時不退出程序。
-h 顯示用法信息,其實就是ab -help。
Nginx壓測和並發預估
預估算法: { (?G) * 1024 - system} / 請求大小
#(?G):表示內存大小
# 1024:表示內存容量標准進制
# system:表示系統和服務占用的額外內存和需要預留的內存
# 請求大小:表示靜態(一般為KB)或動態(一般為MB)的請求大小
# 16核32G服務器,可以抗住4萬多用於負載均衡的並發,最多可以抗住5-6萬
簡單使用下ab壓測工具
ab -n2000 -c2 http://127.0.0.1/index.html # -n 總的請求次數# -c 並發請求數# -k 是否開啟長連接Server Software: nginx/1.12.2 Server Hostname: 127.0.0.1 Server Port: 80Document Path: /index.htmlDocument Length: 19 bytes #頁面長度Concurrency Level: 200Time taken for tests: 1.013 seconds # 總花費總時長Complete requests: 2000 # 總請求數Failed requests: 0 # 請求失敗數Write errors: 0Total transferred: 510000 bytes # 總共傳輸字節數,包含http的頭信息等HTML transferred: 38000 bytes # html字節數,實際的頁面傳遞字節數Requests per second: 9333.23 [#/sec] (mean) # 每秒多少請求/s(總請求出/總共完成的時間)Time per request: 101.315 [ms] (mean) # 客戶端訪問服務端, 單個請求所需花費的時間Time per request: 0.507 [ms] (mean, across all concurrent requests) # 服務端處理請求的時間Transfer rate: 491.58 [Kbytes/sec] received # 判斷網絡傳輸速率, 觀察網絡是否存在瓶頸 [root@node-a ~]# ab -c 20000 -n 80000 http://1.1.1.1/index.htmlThis is ApacheBench, Version 2.3 <$Revision: 1430300 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 1.1.1.1 (be patient)Completed 8000 requestsCompleted 16000 requestsCompleted 24000 requestsCompleted 32000 requestsCompleted 40000 requestsCompleted 48000 requestsCompleted 56000 requestsCompleted 64000 requestsCompleted 72000 requestsCompleted 80000 requestsFinished 80000 requestsServer Software: nginx/1.16.0 # 服務器信息和版本Server Hostname: 1.1.1.1 # 服務器的域名Server Port: 80 # 端口Document Path: /index.html # 訪問路徑Document Length: 612 bytes # 文檔大小 612bytes (此為http響應的正文長度)Concurrency Level: 20000 # 並發請求數Time taken for tests: 3.735 seconds # 整個測試持續時間,默認秒Complete requests: 80000 # 完成請求數Failed requests: 1 # 失敗請求數(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)Write errors: 0 # 網絡連接寫入錯誤數Non-2xx responses: 1Total transferred: 67599494 bytes # 傳輸總數據量HTML transferred: 48959565 bytes # 傳輸HTML內容傳輸量Requests per second: 21418.17 [#/sec] (mean) # 每秒多少請求,這個是非常重要的參數數值,服務器的吞吐量Time per request: 933.787 [ms] (mean) # 所有用戶請求一次的平均時間Time per request: 0.047 [ms] (mean, across all concurrent requests) # 服務器平均處理時間,也就是服務器吞吐量的倒數Transfer rate: 17674.04 [Kbytes/sec] received # 傳輸速率Connection Times (ms) min mean[+/-sd] median maxConnect: 0 171 573.6 7 3022Processing: 2 15 30.6 10 807Waiting: 1 12 30.1 8 805Total: 5 186 583.0 18 3437Percentage of the requests served within a certain time (ms) 50% 18 # 50%的請求在183ms內返回 66% 20 75% 25 80% 30 90% 455 95% 1037 98% 3031 99% 3041 100% 3437 (longest request)
查看並發連接數和連接狀態
查看Web服務器(Nginx Apache)的並發請求數及其TCP連接狀態
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'
返回結果一般如下
# LAST_ACK 5 (正在等待處理的請求數)# SYN_RECV 30# ESTABLISHED 1597 (正常數據傳輸狀態)# FIN_WAIT1 51# FIN_WAIT2 504# TIME_WAIT 1057 (處理完畢,等待超時結束的請求數)
其他參數說明
# CLOSED:無連接是活動的或正在進行
# LISTEN:服務器在等待進入呼叫
# SYN_RECV:一個連接請求已經到達,等待確認
# SYN_SENT:應用已經開始,打開一個連接
# ESTABLISHED:正常數據傳輸狀態
# FIN_WAIT1:應用說它已經完成
# FIN_WAIT2:另一邊已同意釋放
# ITMED_WAIT:等待所有分組死掉
# CLOSING:兩邊同時嘗試關閉
# TIME_WAIT:另一邊已初始化一個釋放
# LAST_ACK:等待所有分組死掉
查看Nginx和Apache的運行進程數
ps -ef | grep nginx | wc -l
ps -ef | grep httpd | wc -l
查看Web服務器進程連接數
netstat -antp | grep 80 | grep ESTABLISHED -c
優化案例(8c16g)
優化前
服務器配置(8c16g)
- time用於計時
- dd用於復制,從if讀出,寫到of;
- if=/dev/zero不產生IO,因此可以用來測試純寫速度;同理of=/dev/null不產生IO,可以用來測試純讀速度。
- bs是每次讀或寫的大小,即一個塊的大小,count是讀寫塊的數量,相乘就是讀寫數據量大小;
數據量越大越准確,多次測試取平均值;
開啟nginx的status模塊
# 在 nginx.conf 中配置統計模塊
location /status{
# 開啟狀態
stub_status on;
# 不需要日志
access_log off;
# 只允許此 ip 訪問
allow 192.168.222.101;
# 其他 ip 禁止訪問
deny all;
}
也可以使用Webbench壓測,下面僅供參考
ab壓測信息
[root@node-a ~]# ab -c 20000 -n 100000 http://1.1.1.1/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 1.1.1.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.16.0
Server Hostname: 1.1.1.1
Server Port: 80
Document Path: /index.html
Document Length: 612 bytes
Concurrency Level: 20000
Time taken for tests: 64.315 seconds
Complete requests: 100000
Failed requests: 5
(Connect: 0, Receive: 0, Length: 5, Exceptions: 0)
Write errors: 0
Non-2xx responses: 2
Total transferred: 84496453 bytes
HTML transferred: 61197294 bytes
Requests per second: 1554.84 [#/sec] (mean)
Time per request: 12863.025 [ms] (mean)
Time per request: 0.643 [ms] (mean, across all concurrent requests)
Transfer rate: 1283.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 118 473.7 6 3018
Processing: 2 14 330.5 9 60001
Waiting: 0 10 35.5 7 1612
Total: 4 132 583.7 15 60001
Percentage of the requests served within a certain time (ms)
50% 15
66% 18
75% 19
80% 20
90% 25
95% 1018
98% 3018
99% 3024
100% 60001 (longest request)
優化后
每個請求都需要建立 socket 連接,那么影響並發量的因素之一;
客戶端不允許一次性創建過多的連接
服務端不允許一次性創建過多的連接
每個請求都要訪問一些資源,那么影響並發量的因素之一:
服務端不允許一個文件在同一時間點被訪問 N 次,相當於一個文件在服務端打開 N 次
我們在使用 ab 模擬並發訪問后,執行 dmesg 命令,查看請求的信息
dmesg
# 執行結果的最后一行為:possible SYN flooding on port 80. Sending cookies.
# 解釋:在同一時間有過多的請求訪問 80 端口,導致系統誤認為遭受了洪水攻擊
從上面的優化分析中,我們可以從 socket 和文件兩個層面進行 Nginx 的高並發優化
socket:分為系統層面和 nginx 層面:
系統層面
# 禁止洪水抵御,這個操作在重啟之后失效
命令:more /proc/sys/net/ipv4/tcp_syncookies
結果:1
命令:echo 0 > /proc/sys/net/ipv4/tcp_syncookies
# 最大連接數,這個操作在重啟之后失效
命令:more /proc/sys/net/core/somaxconn
結果:128
命令:echo 50000 > /proc/sys/net/core/somaxconn
# 加快 tcp 連接的回收,這個操作在重啟之后失效
命令:cat /proc/sys/net/ipv4/tcp_tw_recycle
結果:0
命令:echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
# 使空的 tcp 連接重新被利用,這個操作在重啟之后失效
命令:cat /proc/sys/net/ipv4/tcp_tw_reuse
結果:0
命令:echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
# 完整的命令
echo 50000 > /proc/sys/net/core/somaxconn
echo 0 > /proc/sys/net/ipv4/tcp_syncookies
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
sysctl -w net.ipv4.tcp_timestamps=1 開啟對於TCP時間戳的支持,若該項設置為0,則下面一項設置不起作用
sysctl -w net.ipv4.tcp_tw_recycle=1
vm.max_map_count = 262144
再次壓測nginx
[root@node-a ~]# ab -c 20000 -n 100000 http://1.1.1.1/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 1.1.1.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.16.0
Server Hostname: 1.1.1.1
Server Port: 80
Document Path: /index.html
Document Length: 612 bytes
Concurrency Level: 20000
Time taken for tests: 4.690 seconds
Complete requests: 100000
Failed requests: 1
(Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors: 0
Non-2xx responses: 1
Total transferred: 84499494 bytes
HTML transferred: 61199565 bytes
Requests per second: 21320.91 [#/sec] (mean)
Time per request: 938.046 [ms] (mean)
Time per request: 0.047 [ms] (mean, across all concurrent requests)
Transfer rate: 17593.81 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 140 485.5 6 3020
Processing: 2 14 47.0 9 1604
Waiting: 0 12 46.9 7 1604
Total: 2 154 499.6 16 4619
Percentage of the requests served within a certain time (ms)
50% 16
66% 20
75% 22
80% 25
90% 411
95% 1023
98% 3018
99% 3027
100% 4619 (longest request)
nginx
# 子進程允許打開的連接數(nginx.conf)及 IO 選擇
events {
worker_processes 8;
# 子進程連接數
worker_connections 65535;
# 使用 linux 下的多路復用 IO,是 poll 增強版本
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
#sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_header_timeout 60;
client_body_timeout 60;
reset_timedout_connection on;
send_timeout 600;
client_max_body_size 100m;
client_body_buffer_size 256k;
client_body_temp_path /var/cache/nginx/client_temp;
gzip on;
gzip_static on;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_types text/css text/xml application/javascript;
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
include /etc/nginx/conf.d/*.conf;
}
# 將 keepalive_timeout 設置為 0,高並發網站中,一般不超過 2s。此參數在 F12 調試頁面時,在 Network 的 Headers 的 Response Headers 下可以看到 Connection:keep-alive,如果設置為 0,那么為 Connection:close
keepalive_timeout 0;
再次壓測
[root@node-a ~]# ab -c 20000 -n 100000 http://1.1.1.1/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 1.1.1.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.16.0
Server Hostname: 1.1.1.1
Server Port: 80
Document Path: /index.html
Document Length: 612 bytes
Concurrency Level: 20000
Time taken for tests: 4.613 seconds
Complete requests: 100000
Failed requests: 16
(Connect: 0, Receive: 0, Length: 16, Exceptions: 0)
Write errors: 0
Non-2xx responses: 16
Total transferred: 84491904 bytes
HTML transferred: 61193040 bytes
Requests per second: 21676.88 [#/sec] (mean)
Time per request: 922.642 [ms] (mean)
Time per request: 0.046 [ms] (mean, across all concurrent requests)
Transfer rate: 17885.95 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 361 704.8 130 3198
Processing: 2 122 72.5 134 730
Waiting: 1 79 50.5 88 403
Total: 3 483 723.6 305 3354
Percentage of the requests served within a certain time (ms)
50% 305
66% 318
75% 339
80% 757
90% 1111
95% 3251
98% 3298
99% 3325
100% 3354 (longest request)
文件層面
系統層面
# 設置同一個文件同一時間點可以打開 N 次,這個操作在重啟之后失效
命令:ulimit -n
返回:128
命令:ulimit -n 200000
nginx 層面
# nginx 進程數,按照 CPU 數目指定
worker_processes 8;
# nginx 子進程允許打開的文件次數
worker_rlimit_nofile 102400;
再次壓測
[root@node-a ~]# ab -c 20000 -n 100000 http://1.1.1.1/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 1.1.1.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.16.0
Server Hostname: 1.1.1.1
Server Port: 80
Document Path: /index.html
Document Length: 612 bytes
Concurrency Level: 20000
Time taken for tests: 4.560 seconds
Complete requests: 100000
Failed requests: 25
(Connect: 0, Receive: 0, Length: 25, Exceptions: 0)
Write errors: 0
Non-2xx responses: 25
Total transferred: 84487350 bytes
HTML transferred: 61189125 bytes
Requests per second: 21930.98 [#/sec] (mean)
Time per request: 911.952 [ms] (mean)
Time per request: 0.046 [ms] (mean, across all concurrent requests)
Transfer rate: 18094.64 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 285 493.8 127 3196
Processing: 7 112 93.6 128 1750
Waiting: 0 67 71.7 54 1734
Total: 15 397 532.1 249 3595
Percentage of the requests served within a certain time (ms)
50% 249
66% 339
75% 348
80% 612
90% 1183
95% 1312
98% 1492
99% 3343
100% 3595 (longest request)
小結
適合單個URL的測試,可以支持更多方式去測試,比如使用cookie模仿用戶提交表單來測試數據庫,但ab是單線程的,不適合測性能高的服務器;
ab並發數不能大於請求數
請求數默認不能超過1024個
ab並發默認不能大於20000, 需要修改apache源代碼support目錄下ab.c文件,找到:#define MAX_CONCURRENCY 20000 將宏定義的值改大,重新編譯安裝apache。
ab可以直接在Web服務器本地發起測試請求,不包括數據的網絡傳輸時間以及用戶PC本地的計算時間;
沒修改內核參數並發超過一千會報錯,連接被重置,bingyi了以下,apr_socket_recv這個是操作系統內核的一個參數,在高並發的情況下,內核會認為系統受到了SYN flood攻擊,會發送cookies(possible SYN flooding on port 80. Sending cookies),這樣會減慢影響請求的速度,所以在應用服務武器上設置下這個參數為0禁用系統保護就可以進行大並發測試了;