使用 cURL 對 HTTP Requests 進行性能測試

benchmarking.jpeg

在做 Web 開發(fā)的時候,經(jīng)常需要對 Web Page 或者 REST-ful API 做簡單的 Benchmark。本文將介紹如何使用 cURL 進行簡單快速的 Benchmark。

本文內(nèi)容涉及:

  • 使用 curl 查看加載時間
  • 使用 curl -w 查看更多的網(wǎng)絡(luò)情況
  • 使用 Apache Benchmark(ab) 進行更高級的 Benchmark

當(dāng)然,最后還會涉及實戰(zhàn)應(yīng)用。

使用 curl 查看加載時間

?  blogs git:(curl) ? curl -s -w "%{time_total}\n" -o /dev/null http://www.github.com/
1.492

可以看到請求時間為 1.492 秒。此時:

  • -s, --silent: 讓 curl 保持靜默模式,不會輸出進度條
  • -w "%{time_total\n}":輸出使用時間
  • -o /dev/null: 這個參數(shù)用來隱藏 response 的內(nèi)容

如果使用 time 可以看到 time_total 的細節(jié):

?  blogs git:(curl) ? time curl -s -o /dev/null http://www.github.com/
curl --silent -o /dev/null http://www.github.com/  1.04s user 0.04s system 61% cpu 1.760 total

通常情況 Benchmark 一次的數(shù)據(jù)并不可靠,可以配合 for loop 發(fā)送多次請求:

# zsh shell
?  blogs git:(curl) ? for i in {1..3}; curl -s -w "%{time_total}\n" -o /dev/null http://www.github.com/
0.665
0.678
1.399

curl 默認發(fā)送 GET 請求,可以使用 TL;DR 查看發(fā)送 POST, DELETE, PUT 或者更多的使用方法。

使用 curl -w 查看更多的網(wǎng)絡(luò)情況

通常情況下一個 HTTP Request 會包含很多步驟,如果想知道 time_total 之外更詳細的信息,可以參考 man curl 文章中, -w --write-out <format>

curl -w <format> 可以支持格式模板,我們可以使用 @template-file-name 的方式對輸出格式進行自定義。

比如將這個模板保存為 curl-format.txt

\n
            time_namelookup:  %{time_namelookup}\n
               time_connect:  %{time_connect}\n
            time_appconnect:  %{time_appconnect}\n
           time_pretransfer:  %{time_pretransfer}\n
              time_redirect:  %{time_redirect}\n
         time_starttransfer:  %{time_starttransfer}\n
                            ----------\n
                 time_total:  %{time_total}\n
\n
?  blogs git:(curl) ? curl -s -w "@curl-format.txt" -o /dev/null http://www.baidu.com/

            time_namelookup:  1.101
               time_connect:  1.130
            time_appconnect:  0.000
           time_pretransfer:  1.130
              time_redirect:  0.000
         time_starttransfer:  1.164
                            ----------
                 time_total:  1.165

此時可以看到 DNS lookup, TCP 鏈接,數(shù)據(jù)傳傳輸?shù)刃畔ⅰ?/p>

使用 Apache Benchmark(ab) 進行更高級的 Benchmark

以上使用 curl 進行的簡單的 Benchmark 都是基于單線程的訪問。如果需要更多詳細信息,或者希望進行并發(fā)測試,推薦使用 Apache Benchmark

例如,我們希望對 github.com 做個 10 * Requests,3 * concurrency 的 Benchmark。

?  blogs git:(curl) ? ab -n 10 -c 3 http://github.com/
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking github.com (be patient).....done


Server Software:
Server Hostname:        github.com
Server Port:            80

Document Path:          /
Document Length:        0 bytes

Concurrency Level:      3
Time taken for tests:   3.293 seconds
Complete requests:      10
Failed requests:        0
Non-2xx responses:      10
Total transferred:      1030 bytes
HTML transferred:       0 bytes
Requests per second:    3.04 [#/sec] (mean)
Time per request:       987.954 [ms] (mean)
Time per request:       329.318 [ms] (mean, across all concurrent requests)
Transfer rate:          0.31 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      255  488 419.1    270    1282
Processing:   257  485 354.1    277    1179
Waiting:      257  485 354.1    277    1179
Total:        512  973 616.2    556    2196

Percentage of the requests served within a certain time (ms)
  50%    556
  66%   1125
  75%   1537
  80%   1640
  90%   2196
  95%   2196
  98%   2196
  99%   2196
 100%   2196 (longest request)

此時我們可以得到更詳細的 Benchmark 信息。

實戰(zhàn)應(yīng)用

最近項目的 Tech Leader 對一段代碼提出了 Performance 的 issue。這段代碼在 map 操作時做了大量的同步網(wǎng)絡(luò)請求。代碼大致如下:

data_set.map do |item|
  # request 1 with item.property
  # request 2 with item.property
  # request 3 with item.property
end

Tead Leader 使用 curl 給出了簡單的 Benchmark。

time curl -X "GET" URL
0.03s user 0.01s system 0% cpu 4.220 total

這段代碼 data_set 大小至少為 20,每一個 map 參考至少會發(fā)送 3 個網(wǎng)絡(luò)請求。總網(wǎng)絡(luò)請求數(shù)會達到 20 * 3 = 60 次,并且這些 HTTP Request 都以同步的方式進行。
因此希望采用異步的方式優(yōu)化 map 操作。方案采用 Ruby 中的 parallel gem。

Parallel.map(data_set, in_threads: {thread_number}) do |item|
  # request 1 with item.property
  # request 2 with item.property
  # request 3 with item.property
end

此時如何給出合理的 thread_number,需要參考 Benchmark 結(jié)果。之后采用 Apache Benchmarkthread_number 進行挑選。

  1. 對 API 進行單次請求,確定 Benchmark baseline,之后的有話都必須比這個 baseline 快。

    ab -n 1 URL
    
  2. 調(diào)整 thread_number,分別對 API 進行多次同步請求,選出最佳 thread_number

    ab -n 5 URL
    
  3. 調(diào)整 thread_number,再對 API 進行 concurrency benchmark,選出最佳 thread_number

    ab -n 15 -c 3 URL
    

分享一組數(shù)據(jù):

Base line 為進行優(yōu)化的時間:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing: 13076 13076   0.0  13076   13076
Waiting:    13075 13075   0.0  13075   13075
Total:      13076 13076   0.0  13076   13076

6 * Thread 優(yōu)化之后的時間(Win):

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:  2492 2492   0.0   2492    2492
Waiting:     2492 2492   0.0   2492    2492
Total:       2492 2492   0.0   2492    2492

10 * Thread 優(yōu)化之后的時間:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:  6098 6098   0.0   6098    6098
Waiting:     6098 6098   0.0   6098    6098
Total:       6098 6098   0.0   6098    6098

由此數(shù)據(jù)可見, 6 * Thread 是最合適并行數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,915評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 轉(zhuǎn)載自:http://www.cnblogs.com/txw1958/archive/2013/01/19/286...
    php_bruce閱讀 2,304評論 1 5
  • 風(fēng)雨三十年,真情依然鮮,武全定和鄧雪倩結(jié)婚三十周年紀念。
    小橡皮樹閱讀 346評論 0 1
  • 從小在部隊大院長大,對大院的記憶卻是斷斷續(xù)續(xù),很多的人和事都已模糊,仿佛沉淀在記憶深處,或許某年某月某天某件事會突...
    好風(fēng)如水yt閱讀 308評論 0 1