上一節,咱們回顧了經典的 C10K 和 C1000K 問題。簡單回顧一下,C10K 是指如何單機同時處理 1 萬個請求(併發鏈接 1 萬)的問題,而 C1000K 則是單機支持處理 100 萬個
請求(併發鏈接 100 萬)的問題。nginx
I/O 模型的優化,是解決 C10K 問題的最佳良方。Linux 2.6 中引入的 epoll,完美解決了C10K 的問題,並一直沿用至今。今天的不少高性能網絡方案,仍都基於 epoll。git
天然,隨着互聯網技術的普及,催生出更高的性能需求。從 C10K 到 C100K,咱們只須要增長系統的物理資源,就能夠知足要求;但從 C100K 到 C1000K ,光增長物理資源就不夠了。github
這時,就要對系統的軟硬件進行統一優化,從硬件的中斷處理,到網絡協議棧的文件描述符數量、鏈接狀態跟蹤、緩存隊列,再到應用程序的工做模型等的整個網絡鏈路,都須要深刻優化。web
再進一步,要實現 C10M,就不是增長物理資源、調優內核和應用程序能夠解決的問題了。這時內核中冗長的網絡協議棧就成了最大的負擔。docker
須要用 XDP 方式,在內核協議棧以前,先處理網絡包。
或基於 DPDK ,直接跳過網絡協議棧,在用戶空間經過輪詢的方式處理。apache
其中,DPDK 是目前最主流的高性能網絡方案,不過,這須要能支持 DPDK 的網卡配合使用。vim
固然,實際上,在大多數場景中,咱們並不須要單機併發 1000 萬請求。經過調整系統架構,把請求分發到多臺服務器中並行處理,纔是更簡單、擴展性更好的方案。緩存
不過,這種狀況下,就須要咱們評估系統的網絡性能,以便考察系統的處理能力,併爲容量規劃提供基準數據。性能優化
那麼,到底該怎麼評估網絡的性能呢?今天,我就帶你一塊兒來看看這個問題。bash
在評估網絡性能前,咱們先來回顧一下,衡量網絡性能的指標。在 Linux 網絡基礎篇中,咱們曾經說到,帶寬、吞吐量、延時、PPS 等,都是最經常使用的網絡性能指標。還記得它們
的具體含義嗎?你能夠先思考一下,再繼續下面的內容。
首先,帶寬,表示鏈路的最大傳輸速率,單位是 b/s(比特 / 秒)。在你爲服務器選購網卡時,帶寬就是最核心的參考指標。經常使用的帶寬有 1000M、10G、40G、100G 等。
第二,吞吐量,表示沒有丟包時的最大數據傳輸速率,單位一般爲 b/s (比特 / 秒)或者B/s(字節 / 秒)。吞吐量受帶寬的限制,吞吐量 / 帶寬也就是該網絡鏈路的使用率。
第三,延時,表示從網絡請求發出後,一直到收到遠端響應,所須要的時間延遲。這個指標在不一樣場景中可能會時),或者一個數據包往返所需時間(好比 RTT)。
最後,PPS,是 Packet Per Second(包 / 秒)的縮寫,表示以網絡包爲單位的傳輸速率。PPS 一般用來評估網絡的轉發能力,而基於 Linux 服務器的轉發,很容易受到網絡包
大小的影響(交換機一般不會受到太大影響,即交換機能夠線性轉發)。
這四個指標中,帶寬跟物理網卡配置是直接關聯的。通常來講,網卡肯定後,帶寬也就肯定了(固然,實際帶寬會受限於整個網絡鏈路中最小的那個模塊)。
另外,你可能在不少地方據說過「網絡帶寬測試」,這裏測試的實際上不是帶寬,而是網絡吞吐量。Linux 服務器的網絡吞吐量通常會比帶寬小,而對交換機等專門的網絡設備來
說,吞吐量通常會接近帶寬。
最後的 PPS,則是以網絡包爲單位的網絡傳輸速率,一般用在須要大量轉發的場景中。而對 TCP 或者 Web 服務來講,更多會用併發鏈接數和每秒請求數(QPS,Query per
Second)等指標,它們更能反應實際應用程序的性能。
熟悉了網絡的性能指標後,接下來,咱們再來看看,如何經過性能測試來肯定這些指標的基準值。
你能夠先思考一個問題。咱們已經知道,Linux 網絡基於 TCP/IP 協議棧,而不一樣協議層的行爲顯然不一樣。那麼,測試以前,你應該弄清楚,你要評估的網絡性能,究竟屬於協議棧
的哪一層?換句話說,你的應用程序基於協議棧的哪一層呢?
根據前面學過的 TCP/IP 協議棧的原理,這個問題應該不難回答。好比:
接下來,我就帶你從下往上,瞭解不一樣協議層的網絡性能測試方法。不過要注意,低層協議是其上的各層網絡協議的基礎。天然,低層協議的性能,也就決定了高層的網絡性能。
注意,如下全部的測試方法,都須要兩臺 Linux 虛擬機。其中一臺,能夠看成待測試的目標機器;而另外一臺,則能夠看成正在運行網絡服務的客戶端,用來運行測試工具。
咱們首先來看,網絡接口層和網絡層,它們主要負責網絡包的封裝、尋址、路由以及發送和接收。在這兩個網絡協議層中,每秒可處理的網絡包數 PPS,就是最重要的性能指標。
特別是 64B 小包的處理能力,值得咱們特別關注。那麼,如何來測試網絡包的處理能力呢?
說到網絡包相關的測試,你可能會以爲陌生。不過,其實在專欄開頭的 CPU 性能篇中,咱們就接觸過一個相關工具,也就是軟中斷案例中的 hping3。
在那個案例中,hping3 做爲一個 SYN 攻擊的工具來使用。實際上, hping3 更多的用途,是做爲一個測試網絡包處理能力的性能工具。
今天我再來介紹另外一個更經常使用的工具,Linux 內核自帶的高性能網絡測試工具 pktgen。pktgen 支持豐富的自定義選項,方便你根據實際須要構造所需網絡包,從而更準確地測
試出目標服務器的性能。
不過,在 Linux 系統中,你並不能直接找到 pktgen 命令。由於 pktgen 做爲一個內核線程來運行,須要你加載 pktgen 內核模塊後,再經過 /proc 文件系統來交互。下面就是
pktgen 啓動的兩個內核線程和 /proc 文件系統的交互文件:
modprobe pktgen $ ps -ef | grep pktgen | grep -v grep root 26384 2 0 06:17 ? 00:00:00 [kpktgend_0] root 26385 2 0 06:17 ? 00:00:00 [kpktgend_1] $ ls /proc/net/pktgen/ kpktgend_0 kpktgend_1 pgctrl
pktgen 在每一個 CPU 上啓動一個內核線程,並能夠經過 /proc/net/pktgen 下面的同名文件,跟這些線程交互;而 pgctrl 則主要用來控制此次測試的開啓和中止。
若是 modprobe 命令執行失敗,說明你的內核沒有配置 CONFIG_NET_PKTGEN 選項。這就須要你配置 pktgen 內核模塊(即 CONFIG_NET_PKTGEN=m)後,從新編譯內核,纔可使用
在使用 pktgen 測試網絡性能時,須要先給每一個內核線程 kpktgend_X 以及測試網卡,配置 pktgen 選項,而後再經過 pgctrl 啓動測試。
以發包測試爲例,假設發包機器使用的網卡是 eth0,而目標機器的 IP 地址爲192.168.0.30,MAC 地址爲 11:11:11:11:11:11。
接下來,就是一個發包測試的示例。
# 定義一個工具函數,方便後面配置各類測試選項 function pgset() { local result echo $1 > $PGDEV result=`cat $PGDEV | fgrep "Result: OK:"` if [ "$result" = "" ]; then cat $PGDEV | fgrep Result: fi } # 爲 0 號線程綁定 eth0 網卡 PGDEV=/proc/net/pktgen/kpktgend_0 pgset "rem_device_all" # 清空網卡綁定 pgset "add_device eth0" # 添加 eth0 網卡 # 配置 eth0 網卡的測試選項 PGDEV=/proc/net/pktgen/eth0 pgset "count 1000000" # 總髮包數量 pgset "delay 5000" # 不一樣包之間的發送延遲 (單位納秒) pgset "clone_skb 0" # SKB 包複製 pgset "pkt_size 64" # 網絡包大小 pgset "dst 192.168.0.30" # 目的 IP pgset "dst_mac 11:11:11:11:11:11" # 目的 MAC # 啓動測試 PGDEV=/proc/net/pktgen/pgctrl pgset "start"
稍等一下子,測試完成後,結果能夠從 /proc 文件系統中獲取。經過下面代碼段中的內容,咱們能夠查看剛纔的測試報告:
cat /proc/net/pktgen/eth0 Params: count 1000000 min_pkt_size: 64 max_pkt_size: 64 frags: 0 delay: 0 clone_skb: 0 ifname: eth0 flows: 0 flowlen: 0 ... Current: pkts-sofar: 1000000 errors: 0 started: 1534853256071us stopped: 1534861576098us idle: 70673us ... Result: OK: 8320027(c8249354+d70673) usec, 1000000 (64byte,0frags) 120191pps 61Mb/sec (61537792bps) errors: 0
你能夠看到,測試報告主要分爲三個部分:
第一部分的 Params 是測試選項;
第二部分的 Current 是測試進度,其中, packts so far(pkts-sofar)表示已經發送了100 萬個包,也就代表測試已完成。
第三部分的 Result 是測試結果,包含測試所用時間、網絡包數量和分片、PPS、吞吐量以及錯誤數。
根據上面的結果,咱們發現,PPS 爲 12 萬,吞吐量爲 61 Mb/s,沒有發生錯誤。那麼,12 萬的 PPS 好很差呢?
實際測試代碼以下:
[root@69 ~]# modprobe pktgen [root@69 ~]# ps -ef|grep pktgen |grep -v grep root 1434 2 0 19:55 ? 00:00:00 [kpktgend_0] root 1435 2 0 19:55 ? 00:00:00 [kpktgend_1] [root@69 ~]# ls /proc/net/pktgen/ kpktgend_0 kpktgend_1 pgctrl [root@69 ~]# function pgset() { > local result > echo $1 > $PGDEV > > result=`cat $PGDEV | fgrep "Result: OK:"` > if [ "$result" = "" ]; then > cat $PGDEV | fgrep Result: > fi > } [root@69 ~]# PGDEV=/proc/net/pktgen/kpktgend_0 [root@69 ~]# pgset "rem_device_all" # 清空網卡綁定 [root@69 ~]# pgset "add_device eno1" # 添加 eno1 網卡 [root@69 ~]# PGDEV=/proc/net/pktgen/eno1 [root@69 ~]# pgset "count 1000000" # 總髮包數量 目的 IP pgset "dst_mac 94:18:82:0a:70:b0" # 目的 MAC [root@69 ~]# pgset "delay 5000" # 不一樣包之間的發送延遲 (單位納秒) [root@69 ~]# pgset "clone_skb 0" # SKB 包複製 [root@69 ~]# pgset "pkt_size 64" # 網絡包大小 [root@69 ~]# pgset "dst 0.0.10.42" # 目的 IP [root@69 ~]# pgset "dst_mac 94:18:82:0a:70:b0" # 目的 MAC [root@69 ~]# PGDEV=/proc/net/pktgen/pgctrl [root@69 ~]# pgset "start" [root@69 ~]# cat /proc/net/pktgen/eno1 Params: count 1000000 min_pkt_size: 64 max_pkt_size: 64 frags: 0 delay: 5000 clone_skb: 0 ifname: eno1 flows: 0 flowlen: 0 queue_map_min: 0 queue_map_max: 0 dst_min: 192.168.118.77 dst_max: src_min: src_max: src_mac: 00:0c:29:b2:f5:5b dst_mac: 00:0c:29:18:a9:e7 udp_src_min: 9 udp_src_max: 9 udp_dst_min: 9 udp_dst_max: 9 src_mac_count: 0 dst_mac_count: 0 Flags: Current: pkts-sofar: 1000000 errors: 0 started: 157688456us stopped: 252745896us idle: 81294us seq_num: 1000001 cur_dst_mac_offset: 0 cur_src_mac_offset: 0 cur_saddr: 0x6d76a8c0 cur_daddr: 0x4d76a8c0 cur_udp_dst: 9 cur_udp_src: 9 cur_queue_map: 0 flows: 0 Result: OK: 95057439(c94976145+d81294) nsec, 1000000 (64byte,0frags) 10519pps 5Mb/sec (5385728bps) errors: 0
做爲對比,你能夠計算一下千兆交換機的 PPS。交換機能夠達到線速(滿負載時,無差錯轉發),它的 PPS 就是 1000Mbit 除以以太網幀的大小,即 1000Mbps/((64+20)*8bit)= 1.5 Mpps
(其中 20B 爲以太網幀的頭部大小)。
你看,即便是千兆交換機的 PPS,也能夠達到 150 萬 PPS,比咱們測試獲得的 12 萬大多了。因此,看到這個數值你並不用擔憂,如今的多核服務器和萬兆網卡已經很廣泛了,稍
作優化就能夠達到數百萬的 PPS。並且,若是你用了上節課講到的 DPDK 或 XDP ,還能達到千萬數量級。
掌握了 PPS 的測試方法,接下來,咱們再來看 TCP 和 UDP 的性能測試方法。說到 TCP和 UDP 的測試,我想你已經很熟悉了,甚至可能一會兒就能想到相應的測試工具,
好比iperf 或者 netperf。
特別是如今的雲計算時代,在你剛拿到一批虛擬機時,首先要作的,應該就是用 iperf ,測試一下網絡性能是否符合預期。
iperf 和 netperf 都是最經常使用的網絡性能測試工具,測試 TCP 和 UDP 的吞吐量。它們都以客戶端和服務器通訊的方式,測試一段時間內的平均吞吐量。
接下來,咱們就以 iperf 爲例,看一下 TCP 性能的測試方法。目前,iperf 的最新版本爲iperf3,你能夠運行下面的命令來安裝:
# Ubuntu apt-get install iperf3 # CentOS yum install iperf3
而後,在目標機器上啓動 iperf 服務端:
# -s 表示啓動服務端,-i 表示彙報間隔,-p 表示監聽端口 $ iperf3 -s -i 1 -p 10000
接着,在另外一臺機器上運行 iperf 客戶端,運行測試:
# -c 表示啓動客戶端,192.168.0.30 爲目標服務器的 IP # -b 表示目標帶寬 (單位是 bits/s) # -t 表示測試時間 # -P 表示併發數,-p 表示目標服務器監聽端口 $ iperf3 -c 192.168.0.30 -b 1G -t 15 -P 2 -p 10000
實際測試代碼以下:
root@luoahong:~# iperf3 -s -i 1 -p 10000 ----------------------------------------------------------- Server listening on 10000 ----------------------------------------------------------- Accepted connection from 192.168.118.109, port 45568 [ 5] local 192.168.118.77 port 10000 connected to 192.168.118.109 port 45570 [ 7] local 192.168.118.77 port 10000 connected to 192.168.118.109 port 45572 [ ID] Interval Transfer Bandwidth [ 5] 0.00-1.00 sec 42.1 MBytes 353 Mbits/sec [ 7] 0.00-1.00 sec 40.9 MBytes 343 Mbits/sec [SUM] 0.00-1.00 sec 83.0 MBytes 696 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - ...... - - - - - - - - - - - - - - - - - - - - - - - - - [ 5] 15.00-15.06 sec 643 KBytes 94.7 Mbits/sec [ 7] 15.00-15.06 sec 1.50 MBytes 226 Mbits/sec [SUM] 15.00-15.06 sec 2.13 MBytes 321 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 5] 0.00-15.06 sec 0.00 Bytes 0.00 bits/sec sender [ 5] 0.00-15.06 sec 550 MBytes 306 Mbits/sec receiver [ 7] 0.00-15.06 sec 0.00 Bytes 0.00 bits/sec sender [ 7] 0.00-15.06 sec 691 MBytes 385 Mbits/sec receiver [SUM] 0.00-15.06 sec 0.00 Bytes 0.00 bits/sec sender [SUM] 0.00-15.06 sec 1.21 GBytes 691 Mbits/sec receiver ----------------------------------------------------------- Server listening on 10000
稍等一下子(15 秒)測試結束後,回到目標服務器,查看 iperf 的報告:
[ ID] Interval Transfer Bandwidth ... [SUM] 0.00-15.04 sec 0.00 Bytes 0.00 bits/sec sender [SUM] 0.00-15.04 sec 1.51 GBytes 860 Mbits/sec receiver
實際測試代碼以下:
[root@69 /]# iperf3 -c 192.168.118.77 -b 1G -t 15 -P 2 -p 10000 Connecting to host 192.168.118.77, port 10000 [ 4] local 192.168.118.109 port 45570 connected to 192.168.118.77 port 10000 [ 6] local 192.168.118.109 port 45572 connected to 192.168.118.77 port 10000 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 4] 0.00-1.00 sec 43.6 MBytes 365 Mbits/sec 0 199 KBytes [ 6] 0.00-1.00 sec 42.5 MBytes 356 Mbits/sec 0 233 KBytes [SUM] 0.00-1.00 sec 86.2 MBytes 722 Mbits/sec 0 - - - - - - - - - - - - - - - - - - - - - - - - - ...... [SUM] 13.00-14.00 sec 77.3 MBytes 649 Mbits/sec 0 - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 14.00-15.00 sec 21.5 MBytes 180 Mbits/sec 0 420 KBytes [ 6] 14.00-15.00 sec 57.5 MBytes 482 Mbits/sec 0 1.13 MBytes [SUM] 14.00-15.00 sec 79.0 MBytes 663 Mbits/sec 0 - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-15.00 sec 552 MBytes 309 Mbits/sec 52 sender [ 4] 0.00-15.00 sec 550 MBytes 307 Mbits/sec receiver [ 6] 0.00-15.00 sec 692 MBytes 387 Mbits/sec 21 sender [ 6] 0.00-15.00 sec 691 MBytes 386 Mbits/sec receiver [SUM] 0.00-15.00 sec 1.21 GBytes 696 Mbits/sec 73 sender [SUM] 0.00-15.00 sec 1.21 GBytes 694 Mbits/sec receiver iperf Done.
最後的 SUM 行就是測試的彙總結果,包括測試時間、數據傳輸量以及帶寬等。按照發送和接收,這一部分又分爲了 sender 和 receiver 兩行。
從測試結果你能夠看到,這臺機器 TCP 接收的帶寬(吞吐量)爲 860 Mb/s, 跟目標的1Gb/s 相比,仍是有些差距的。
傳輸層再往上,到了應用層。有的應用程序,會直接基於 TCP 或 UDP 構建服務。固然,也有大量的應用,基於應用層的協議來構建服務,HTTP 就是最經常使用的一個應用層協
議。好比,經常使用的 Apache、Nginx 等各類 Web 服務,都是基於 HTTP。
要測試 HTTP 的性能,也有大量的工具可使用,好比 ab、webbench 等,都是經常使用的HTTP 壓力測試工具。其中,ab 是 Apache 自帶的 HTTP 壓測工具,主要測試 HTTP 服
務的每秒請求數、請求延遲、吞吐量以及請求延遲的分佈狀況等。
運行下面的命令,你就能夠安裝 ab 工具:、
# Ubuntu $ apt-get install -y apache2-utils # CentOS $ yum install -y httpd-tools
接下來,在目標機器上,使用 Docker 啓動一個 Nginx 服務,而後用 ab 來測試它的性能。
首先,在目標機器上運行下面的命令:
docker run -p 80:80 -itd nginx
而在另外一臺機器上,運行 ab 命令,測試 Nginx 的性能:
# -c 表示併發請求數爲 1000,-n 表示總的請求數爲 10000 $ ab -c 1000 -n 10000 http://192.168.0.30/ ... Server Software: nginx/1.15.8 Server Hostname: 192.168.0.30 Server Port: 80 ... Requests per second: 1078.54 [#/sec] (mean) Time per request: 927.183 [ms] (mean) Time per request: 0.927 [ms] (mean, across all concurrent requests) Transfer rate: 890.00 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 27 152.1 1 1038 Processing: 9 207 843.0 22 9242 Waiting: 8 207 843.0 22 9242 Total: 15 233 857.7 23 9268 Percentage of the requests served within a certain time (ms) 50% 23 66% 24 75% 24 80% 26 90% 274 95% 1195 98% 2335 99% 4663 100% 9268 (longest request)
能夠看到,ab 的測試結果分爲三個部分,分別是請求彙總、鏈接時間彙總還有請求延遲彙總。以上面的結果爲例,咱們具體來看。
在請求彙總部分,你能夠看到:
Requests per second 爲 1074; 每一個請求的延遲(Time per request)分爲兩行,第一行的 927 ms 表示平均延遲,包括了線程運行的調度時間和網絡請求響應時間,而下一行的 0.927ms ,則表示實際請求的響應時間; Transfer rate 表示吞吐量(BPS)爲 890 KB/s。
鏈接時間彙總部分,則是分別展現了創建鏈接、請求、等待以及彙總等的各種時間,包括最小、最大、平均以及中值處理時間。
最後的請求延遲彙總部分,則給出了不一樣時間段內處理請求的百分比,好比, 90% 的請求,均可以在 274ms 內完成。
實際測試代碼以下:
[root@69 ~]# ab -c 1000 -n 10000 http://192.168.118.77/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.118.77 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: nginx/1.17.3 Server Hostname: 192.168.118.77 Server Port: 80 Document Path: / Document Length: 612 bytes Concurrency Level: 1000 Time taken for tests: 10.816 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 8802365 bytes HTML transferred: 6375204 bytes Requests per second: 924.52 [#/sec] (mean) Time per request: 1081.648 [ms] (mean) Time per request: 1.082 [ms] (mean, across all concurrent requests) Transfer rate: 794.72 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 3 453 132.5 469 1608 Processing: 33 579 236.1 532 2195 Waiting: 2 425 224.7 405 1781 Total: 324 1032 232.3 1026 2635 Percentage of the requests served within a certain time (ms) 50% 1026 66% 1055 75% 1073 80% 1081 90% 1105 95% 1304 98% 1952 99% 2424 100% 2635 (longest request)
當你用 iperf 或者 ab 等測試工具,獲得 TCP、HTTP 等的性能數據後,這些數據是否就能表示應用程序的實際性能呢?我想,你的答案應該是否認的。
好比,你的應用程序基於 HTTP 協議,爲最終用戶提供一個 Web 服務。這時,使用 ab工具,能夠獲得某個頁面的訪問性能,但這個結果跟用戶的實際請求,極可能不一致。因
爲用戶請求每每會附帶着各類各類的負載(payload),而這些負載會影響 Web 應用程序內部的處理邏輯,從而影響最終性能。
那麼,爲了獲得應用程序的實際性能,就要求性能工具自己能夠模擬用戶的請求負載,而iperf、ab 這類工具就無能爲力了。幸運的是,咱們還能夠用 wrk、TCPCopy、Jmeter 或
者 LoadRunner 等實現這個目標。
以 wrk 爲例,它是一個 HTTP 性能測試工具,內置了 LuaJIT,方便你根據實際需求,生成所需的請求負載,或者自定義響應的處理方法。
wrk 工具自己不提供 yum 或 apt 的安裝方法,須要經過源碼編譯來安裝。好比,你能夠運行下面的命令,來編譯和安裝 wrk:
https://github.com/wg/wrk $ cd wrk $ apt-get install build-essential -y $ make $ sudo cp wrk /usr/local/bin/
wrk 的命令行參數比較簡單。好比,咱們能夠用 wrk ,來從新測一下前面已經啓動的Nginx 的性能。
# -c 表示併發鏈接數 1000,-t 表示線程數爲 2 $ wrk -c 1000 -t 2 http://192.168.0.30/ Running 10s test @ http://192.168.0.30/ 2 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 65.83ms 174.06ms 1.99s 95.85% Req/Sec 4.87k 628.73 6.78k 69.00% 96954 requests in 10.06s, 78.59MB read Socket errors: connect 0, read 0, write 0, timeout 179 Requests/sec: 9641.31 Transfer/sec: 7.82MB
實際測試代碼:
wrk -c 1000 -t 2 http://192.168.118.77/ [root@69 wrk]# cp wrk /usr/local/bin/ [root@69 wrk]# [root@69 wrk]# wrk -c 1000 -t 2 http://192.168.118.77/ Running 10s test @ http://192.168.118.77/ 2 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 239.20ms 67.72ms 1.72s 82.03% Req/Sec 1.32k 516.14 3.35k 73.33% 24821 requests in 10.08s, 20.12MB read Socket errors: connect 0, read 0, write 0, timeout 39 Requests/sec: 2463.54 Transfer/sec: 2.00MB
這裏使用 2 個線程、併發 1000 鏈接,從新測試了 Nginx 的性能。你能夠看到,每秒請求數爲 9641,吞吐量爲 7.82MB,平均延遲爲 65ms,比前面 ab 的測試結果要好不少。
這也說明,性能工具自己的性能,對性能測試也是相當重要的。不合適的性能工具,並不能準確測出應用程序的最佳性能。
固然,wrk 最大的優點,是其內置的 LuaJIT,能夠用來實現複雜場景的性能測試。wrk 在調用 Lua 腳本時,能夠將 HTTP 請求分爲三個階段,即 setup、running、done,以下圖所示:
好比,你能夠在 setup 階段,爲請求設置認證參數(來自於 wrk 官方示例):
-- example script that demonstrates response handling and -- retrieving an authentication token to set on all future -- requests token = nil path = "/authenticate" request = function() return wrk.format("GET", path) end response = function(status, headers, body) if not token and status == 200 then token = headers["X-Token"] path = "/resource" wrk.headers["X-Token"] = token end end
而在執行測試時,經過 -s 選項,執行腳本的路徑:
wrk -c 1000 -t 2 -s auth.lua http://192.168.0.30/
實際測試代碼以下:
[root@69 ~]# vim auth.lua [root@69 ~]# wrk -c 1000 -t 2 -s auth.lua http://192.168.118.77/ Running 10s test @ http://192.168.118.77/ 2 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 128.05ms 39.13ms 188.87ms 63.23% Req/Sec 1.28k 1.05k 2.63k 66.67% 824 requests in 10.08s, 247.84KB read Non-2xx or 3xx responses: 824 Requests/sec: 81.77 Transfer/sec: 24.59KB
wrk 須要你用 Lua 腳本,來構造請求負載。這對於大部分場景來講,可能已經足夠了 。不過,它的缺點也正是,全部東西都須要代碼來構造,而且工具自己不提供 GUI 環境。
像 Jmeter 或者 LoadRunner(商業產品),則針對複雜場景提供了腳本錄製、回放、GUI 等更豐富的功能,使用起來也更加方便。
今天,我帶你一塊兒回顧了網絡的性能指標,並學習快了網絡性能的評估方法
性能評估是優化網絡性能的前提,只有在你發現網絡性能瓶頸時,才須要進行網絡性能優化。根據TCP/IP協議棧的原理,不一樣協議層關注性能重點不徹底同樣,也就是對應不一樣的性能測試方法好比:
因爲低層協議是高層協議的基礎。因此,通常狀況下,咱們須要從上到下,對每一個協議層進行性能測試,而後根據性能測試的結果,結合 Linux 網絡協議棧的原理,找出致使性能