后端開發都應該了解點接口的壓力測試(Apache Bench版)


背景

小A:小B,最近調你的接口老是超時呀,8秒都還沒返回結果,是不是有性能問題呀!
小B :我看看~~

類似這樣的對話,在現實中是時有發生的,不是特別嚴重的話,往往大家也不會去重視這個事。

尤其是在一些測試資源並不完備的,開發人員對性能測試沒有接觸過的一些公司,遇到這些會顯得更加力不從心。

本着對自己寫出來的東西負責,上線之前,我們都應該對自己的接口進行一個簡單的壓力測試。

其實做這一步也是為了讓我們心里有個度,有個底,不至於說連能承受多少量都不知道。如果什么都不知道,那很容易陷入一個無底深淵,這是一件很可怕的事情。

老黃平時用的比較多的是Apache Bench,當然,jmeter、wrk和vegeta也都是非常不錯的。

說說用這個的原因吧,免安裝,綠色版,開箱(解壓)即用,說白了,老黃其實就是懶鬼~~

jmeter要裝jdk,懶得弄。

wrk/wrk2 要自己編譯,mac上面可以直接安裝,但是我的mac配置不高,不折騰。

vegeta用起來感覺不是很順手,后面再慢慢挖掘。

Apache Bench 介紹

Apache Bench 是Apache服務器自帶的一個web壓力測試工具,簡稱ab。

ab是一個命令行工具,對發起負載的本機要求很低,根據ab命令可以創建很多的並發訪問線程,模擬多個訪問者同時對某一URL地址進行訪問,因此可以用來測試目標服務器的負載壓力。總的來說ab工具小巧簡單,上手學習較快,可以提供需要的基本性能指標,但是沒有圖形化結果,不能監控。

ab進行的測試的本質是基於HTTP協議,可以理解為對web服務器軟件的黑盒性能測試,獲得的一切數據和計算結果,都是可以通過HTTP來解釋的。

Apache Bench 簡單使用

下面的示例都是在CentOS上面的。

通過下面的命令安裝,

yum -y install httpd-tools

裝好之后,運行一下ab -V就可以看到版本信息。

ab -V

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/

運行一下ab -h就可以看到幫助信息。

幫助信息有很多,也比較詳細,老黃把一些常用的參數都添加了注釋,方便大家查看。

其中最常用的兩個參數是 -c-n,當然如果是POST/PUT請求的話,還離不開 -T-p

說了不少廢話,來看看怎么使用才是重點。

下面准備了兩個簡單的接口來進行演示

[ApiController]
[Route("test")]
public class TestController : ControllerBase
{
    [HttpGet]
    public string Get() => "GET";

    [HttpPost]
    public string Post([FromBody]string value) => value;
}

這個接口是跑在docker里面的(一台2c4g的活動雲服務器),下面的圖可以看到具體的信息,還有兩個接口的訪問詳情。

先來壓一下GET請求的接口, 200並發,5000個請求。

ab -c 200 -n 5000 localhost:9000/test

POST請求有點不一樣,要先准備一下body的參數,這里在/tmp目錄創建了一個post.json文件,里面就一個字符串。

cat /tmp/post.json
"Post"

在壓測命令里面,指定Content-Typeapplication/json, 參數的數據文件路徑是/tmp/post.json

同樣也是200並發,5000個請求。

ab -c 200 -n 5000 -T "application/json" -p /tmp/post.json localhost:9000/test

到這里,大家對怎么壓測,應該都不會太陌生了,比較陌生的應該是壓測的結果要怎么看。

下面拿其中一個結果示例來說明各項指標的含義:

Server Software:        Kestrel  # 服務器軟件名稱
Server Hostname:        localhost  # 服務器主機名
Server Port:            9000  # 服務器端口

Document Path:          /test  # 測試的URL路徑
Document Length:        3 bytes  # 文檔大小

Concurrency Level:      200  # 並發數
Time taken for tests:   2.386 seconds  # 消耗的總時間
Complete requests:      5000  # 總次數
Failed requests:        0  # 失敗的請求數
Write errors:           0  # 網絡連接寫入錯誤數
Total transferred:      680000 bytes  # 傳輸的總數據量
HTML transferred:       15000 bytes  # HTML文檔的總數據量
Requests per second:    2095.43 [#/sec] (mean)  # (平均每秒的請求數) 這個是非常重要的參數數值,服務器的吞吐量 
Time per request:       95.446 [ms] (mean)  # (所有並發用戶都請求一次的平均時間)
Time per request:       0.477 [ms] (mean, across all concurrent requests)  # (單個用戶請求一次的平均時間)
Transfer rate:          278.30 [Kbytes/sec] received   # 每秒獲取的數據長度 (傳輸速率,單位:KB/s)

# 網絡上消耗的時間的分解
Connection Times (ms)  
              min  mean[+/-sd] median   max
Connect:        0    3   3.7      2      20
Processing:    12   68 120.0     53    1057
Waiting:        1   67 120.1     52    1050
Total:         15   71 119.8     55    1058

# 整個場景中所有請求的響應情況
Percentage of the requests served within a certain time (ms)
  50%     55
  66%     63
  75%     68
  80%     71
  90%     77
  95%     88
  98%    105
  99%   1012
 100%   1058 (longest request)

這么多的指標,我們可以重點關注下面幾個

  1. Requests per second
  2. Failed requests
  3. 90%,95%和98%的響應時間

第一個是吞吐量,這個上不去,其實是挺尷尬的。

第二個是失敗的請求數,這個數要盡可能的低,最好是0,沒有失敗的。設想一下,100個請求,80個都是失敗的,這個結果還能有意義不。

第三個是響應時間,這個可以看到大部分請求的速度如何。

進行壓測時的一些小建議:

  • 壓測盡可能讓並發數從低往高慢慢遞增,避免一開始就設的太大,一個比較好的參考依據是現在階段線上環境的並發數
  • 壓測的持續時間可以持續久一點,這樣可以看到更多可能出現的情況,可以考慮5分鍾,8分鍾,15分鍾等
  • 有條件的,壓測和被壓測的機器要獨立,因為壓測的時候也會有資源占用,可能會影響被壓測的接口
  • 不要只看壓測的結果數據,還要留意被壓測機的cpu,內存等指標在壓測時是否正常
  • 內網壓測的效果達到預期后,再考慮外網的,網絡因素,可控性不強

分布式壓測和全鏈路壓測,暫時不用想了,留給更專業的人去做吧~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM