壓測工具如何選擇? ab、locust、Jmeter、go壓測工具【單臺機器100w連接壓測實戰】

本文介紹壓測是什麼,解釋壓測的專屬名詞,教大家如何壓測。介紹市面上的常見壓測工具(ab、locust、Jmeter、go實現的壓測工具、雲壓測),對比這些壓測工具,教大家如何選擇一款適合自己的壓測工具,本文還有兩個壓測實戰項目:

  • 單臺機器對HTTP短連接 QPS 1W+ 的壓測實戰
  • 單臺機器100W長連接的壓測實戰

目錄

  • 1、項目說明

    • 1.1 go-stress-testing
    • 1.2 項目體驗
  • 2、壓測

    • 2.1 壓測是什麼
    • 2.2 爲什麼要壓測
    • 2.3 壓測名詞解釋

      • 2.3.1 壓測類型解釋
      • 2.3.2 壓測名詞解釋
      • 2.3.3 機器性能指標解釋
      • 2.3.4 訪問指標解釋
    • 3.4 如何計算壓測指標
  • 3、常見的壓測工具

    • 3.1 ab
    • 3.2 locust
    • 3.3 Jmeter
    • 3.4 雲壓測

      • 3.4.1 雲壓測介紹
      • 3.4.2 阿里雲 性能測試 PTS
      • 3.4.3 騰訊雲 壓測大師 LM
  • 4、go-stress-testing go語言實現的壓測工具

    • 4.1 介紹
    • 4.2 用法
    • 4.3 實現
    • 4.4 go-stress-testing 對 Golang web 壓測
  • 5、壓測工具的比較

    • 5.1 比較
    • 5.2 如何選擇壓測工具
  • 6、單臺機器100w連接壓測實戰

    • 6.1 說明
    • 6.2 內核優化
    • 6.3 客戶端配置
    • 6.4 準備
    • 6.5 壓測數據
  • 7、總結
  • 8、參考文獻

1、項目說明

1.1 go-stress-testing

go 實現的壓測工具,每個用戶用一個協程的方式模擬,最大限度的利用CPU資源

1.2 項目體驗

  • 可以在 mac/linux/windows 不同平臺下執行的命令

參數說明:

-c 表示併發數

-n 每個併發執行請求的次數,總請求的次數 = 併發數 * 每個併發執行請求的次數

-u 需要壓測的地址


# clone 項目
git clone https://github.com/link1st/go-stress-testing.git

# 進入項目目錄
cd go-stress-testing

# 運行 
go run main.go -c 1 -n 100 -u https://www.baidu.com/

  • 壓測結果展示

執行以後,終端每秒鐘都會輸出一次結果,壓測完成以後輸出執行的壓測結果

壓測結果展示:


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────
 耗時│ 併發數 │ 成功數│ 失敗數 │   qps  │最長耗時 │最短耗時│平均耗時 │ 錯誤碼
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────
   1s│      1│      8│      0│    8.09│  133.16│  110.98│  123.56│200:8
   2s│      1│     15│      0│    8.02│  138.74│  110.98│  124.61│200:15
   3s│      1│     23│      0│    7.80│  220.43│  110.98│  128.18│200:23
   4s│      1│     31│      0│    7.83│  220.43│  110.23│  127.67│200:31
   5s│      1│     39│      0│    7.81│  220.43│  110.23│  128.03│200:39
   6s│      1│     46│      0│    7.72│  220.43│  110.23│  129.59│200:46
   7s│      1│     54│      0│    7.79│  220.43│  110.23│  128.42│200:54
   8s│      1│     62│      0│    7.81│  220.43│  110.23│  128.09│200:62
   9s│      1│     70│      0│    7.79│  220.43│  110.23│  128.33│200:70
  10s│      1│     78│      0│    7.82│  220.43│  106.47│  127.85│200:78
  11s│      1│     84│      0│    7.64│  371.02│  106.47│  130.96│200:84
  12s│      1│     91│      0│    7.63│  371.02│  106.47│  131.02│200:91
  13s│      1│     99│      0│    7.66│  371.02│  106.47│  130.54│200:99
  13s│      1│    100│      0│    7.66│  371.02│  106.47│  130.52│200:100


*************************  結果 stat  ****************************
處理協程數量: 1
請求總數: 100 總請求時間: 13.055 秒 successNum: 100 failureNum: 0
*************************  結果 end   ****************************

參數解釋:

耗時: 程序運行耗時。程序每秒鐘輸出一次壓測結果

併發數: 併發數,啓動的協程數

成功數: 壓測中,請求成功的數量

失敗數: 壓測中,請求失敗的數量

qps: 當前壓測的QPS(每秒鐘處理請求數量)

最長耗時: 壓測中,單個請求最長的響應時長

最短耗時: 壓測中,單個請求最短的響應時長

平均耗時: 壓測中,單個請求平均的響應時長

錯誤碼: 壓測中,接口返回的 code碼:返回次數的集合

2、壓測

2.1 壓測是什麼

壓測,即壓力測試,是確立系統穩定性的一種測試方法,通常在系統正常運作範圍之外進行,以考察其功能極限和隱患。

主要檢測服務器的承受能力,包括用戶承受能力(多少用戶同時玩基本不影響質量)、流量承受等。

2.2 爲什麼要壓測

  • 壓測的目的就是通過壓測(模擬真實用戶的行爲),測算出機器的性能(單臺機器的QPS),從而推算出系統在承受指定用戶數(100W)時,需要多少機器能支撐得住
  • 壓測是在上線前爲了應對未來可能達到的用戶數量的一次預估(提前演練),壓測以後通過優化程序的性能或準備充足的機器,來保證用戶的體驗。

2.3 壓測名詞解釋

2.3.1 壓測類型解釋

壓測類型 解釋
壓力測試(Stress Testing) 也稱之爲強度測試,測試一個系統的最大抗壓能力,在強負載(大數據、高併發)的情況下,測試系統所能承受的最大壓力,預估系統的瓶頸
併發測試(Concurrency Testing) 通過模擬很多用戶同一時刻訪問系統或對系統某一個功能進行操作,來測試系統的性能,從中發現問題(併發讀寫、線程控制、資源爭搶)
耐久性測試(Configuration Testing) 通過對系統在大負荷的條件下長時間運行,測試系統、機器的長時間運行下的狀況,從中發現問題(內存泄漏、數據庫連接池不釋放、資源不回收)

2.3.2 壓測名詞解釋

壓測名詞 解釋
併發(Concurrency) 指一個處理器同時處理多個任務的能力(邏輯上處理的能力)
並行(Parallel) 多個處理器或者是多核的處理器同時處理多個不同的任務(物理上同時執行)
QPS(每秒鐘查詢數量 Query Per Second) 服務器每秒鐘處理請求數量 (req/sec 請求數/秒 一段時間內總請求數/請求時間)
事務(Transactions) 是用戶一次或者是幾次請求的集合
TPS(每秒鐘處理事務數量 Transaction Per Second) 服務器每秒鐘處理事務數量(一個事務可能包括多個請求)
請求成功數(Request Success Number) 在一次壓測中,請求成功的數量
請求失敗數(Request Failures Number) 在一次壓測中,請求失敗的數量
錯誤率(Error Rate) 在壓測中,請求成功的數量與請求失敗數量的比率
最大響應時間(Max Response Time) 在一次事務中,從發出請求或指令系統做出的反映(響應)的最大時間
最少響應時間(Mininum Response Time) 在一次事務中,從發出請求或指令系統做出的反映(響應)的最少時間
平均響應時間(Average Response Time) 在一次事務中,從發出請求或指令系統做出的反映(響應)的平均時間

2.3.3 機器性能指標解釋

機器性能 解釋
CUP利用率(CPU Usage) CUP 利用率分用戶態、系統態和空閒態,CPU利用率是指:CPU執行非系統空閒進程的時間與CPU總執行時間的比率
內存使用率(Memory usage) 內存使用率指的是此進程所開銷的內存。
IO(Disk input/ output) 磁盤的讀寫包速率
網卡負載(Network Load) 網卡的進出帶寬,包量

2.3.4 訪問指標解釋

訪問 解釋
PV(頁面瀏覽量 Page View) 用戶每打開1個網站頁面,記錄1個PV。用戶多次打開同一頁面,PV值累計多次
UV(網站獨立訪客 Unique Visitor) 通過互聯網訪問、流量網站的自然人。1天內相同訪客多次訪問網站,只計算爲1個獨立訪客

2.4 如何計算壓測指標

  • 壓測我們需要有目的性的壓測,這次壓測我們需要達到什麼目標(如:單臺機器的性能爲100QPS?網站能同時滿足100W人同時在線)
  • 可以通過以下計算方法來進行計算:
  • 壓測原則:每天80%的訪問量集中在20%的時間裏,這20%的時間就叫做峯值
  • 公式: ( 總PV數80% ) / ( 每天的秒數20% ) = 峯值時間每秒鐘請求數(QPS)
  • 機器: 峯值時間每秒鐘請求數(QPS) / 單臺機器的QPS = 需要的機器的數量
  • 假設:網站每天的用戶數(100W),每天的用戶的訪問量約爲3000W PV,這臺機器的需要多少QPS?
( 30000000*0.8 ) / (86400 * 0.2) ≈ 1389 (QPS)
  • 假設:單臺機器的的QPS是69,需要需要多少臺機器來支撐?
1389 / 69 ≈ 20

3、常見的壓測工具

3.1 ab

  • 簡介

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

ab屬於一個輕量級的壓測工具,結果不會特別準確,可以用作參考。

  • 安裝
# 在linux環境安裝
sudo yum -y install httpd
  • 用法
Usage: ab [options] [http[s]://]hostname[:port]/path
用法:ab [選項] 地址

選項:
Options are:
    -n requests      #執行的請求數,即一共發起多少請求。
    -c concurrency   #請求併發數。
    -s timeout       #指定每個請求的超時時間,默認是30秒。
    -k               #啓用HTTP KeepAlive功能,即在一個HTTP會話中執行多個請求。默認時,不啓用KeepAlive功能。
  • 壓測命令
# 使用ab壓測工具,對百度的鏈接 請求100次,併發數1
ab -n 100 -c 1 https://www.baidu.com/

壓測結果

~ >ab -n 100 -c 1 https://www.baidu.com/
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 www.baidu.com (be patient).....done


Server Software:        BWS/1.1
Server Hostname:        www.baidu.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128

Document Path:          /
Document Length:        227 bytes

Concurrency Level:      1
Time taken for tests:   9.430 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      89300 bytes
HTML transferred:       22700 bytes
Requests per second:    10.60 [#/sec] (mean)
Time per request:       94.301 [ms] (mean)
Time per request:       94.301 [ms] (mean, across all concurrent requests)
Transfer rate:          9.25 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       54   70  16.5     69     180
Processing:    18   24  12.0     23     140
Waiting:       18   24  12.0     23     139
Total:         72   94  20.5     93     203

Percentage of the requests served within a certain time (ms)
  50%     93
  66%     99
  75%    101
  80%    102
  90%    108
  95%    122
  98%    196
  99%    203
 100%    203 (longest request)
  • 主要關注的測試指標
  • Concurrency Level 併發請求數
  • Time taken for tests 整個測試時間
  • Complete requests 完成請求個數
  • Failed requests 失敗個數
  • Requests per second 吞吐量,指的是某個併發用戶下單位時間內處理的請求數。等效於QPS,其實可以看作同一個統計方式,只是叫法不同而已。
  • Time per request 用戶平均請求等待時間
  • Time per request 服務器處理時間

3.2 Locust

  • 簡介

是非常簡單易用、分佈式、python開發的壓力測試工具。有圖形化界面,支持將壓測數據導出。

  • 安裝
# pip3 安裝locust
pip3  install locust
# 查看是否安裝成功
locust -h
# 運行 Locust 分佈在多個進程/機器庫
pip3 install pyzmq
# webSocket 壓測庫
pip3 install websocket-client
  • 用法

編寫壓測腳本 test.py

from locust import HttpLocust, TaskSet, task

# 定義用戶行爲
class UserBehavior(TaskSet):

    @task
    def baidu_index(self):
        self.client.get("/")


class WebsiteUser(HttpLocust):
    task_set = UserBehavior # 指向一個定義的用戶行爲類
    min_wait = 3000 # 執行事務之間用戶等待時間的下界(單位:毫秒)
    max_wait = 6000 # 執行事務之間用戶等待時間的上界(單位:毫秒)
  • 啓動壓測
locust -f  test.py --host=https://www.baidu.com

訪問 http://localhost:8089 進入壓測首頁

Number of users to simulate 模擬用戶數

Hatch rate (users spawned/second) 每秒鐘增加用戶數

點擊 "Start swarming" 進入壓測頁面

locust 首頁

壓測界面右上角有:被壓測的地址、當前狀態、RPS、失敗率、開始或重啓按鈕

性能測試參數

  • Type 請求的類型,例如GET/POST
  • Name 請求的路徑
  • Request 當前請求的數量
  • Fails 當前請求失敗的數量
  • Median 中間值,單位毫秒,請求響應時間的中間值
  • Average 平均值,單位毫秒,請求的平均響應時間
  • Min 請求的最小服務器響應時間,單位毫秒
  • Max 請求的最大服務器響應時間,單位毫秒
  • Average size 單個請求的大小,單位字節
  • Current RPS 代表吞吐量(Requests Per Second的縮寫),指的是某個併發用戶數下單位時間內處理的請求數。等效於QPS,其實可以看作同一個統計方式,只是叫法不同而已。

locust 壓測頁面

3.3 Jmeter

  • 簡介

Apache JMeter是Apache組織開發的基於Java的壓力測試工具。用於對軟件做壓力測試,它最初被設計用於Web應用測試,但後來擴展到其他測試領域。
JMeter能夠對應用程序做功能/迴歸測試,通過創建帶有斷言的腳本來驗證你的程序返回了你期望的結果。

  • 安裝

訪問 https://jmeter-plugins.org/in... 下載解壓以後即可使用

  • 用法

JMeter的功能過於強大,這裏暫時不介紹用法,可以查詢相關文檔使用(參考文獻中有推薦的教程文檔)

3.4 雲壓測

3.4.1 雲壓測介紹

顧名思義就是將壓測腳本部署在雲端,通過雲端對對我們的應用進行全方位壓測,只需要配置壓測的參數,無需準備實體機,雲端自動給我們分配需要壓測的雲主機,對被壓測目標進行壓測。

雲壓測的優勢:

  1. 輕易的實現分佈式部署
  2. 能夠模擬海量用戶的訪問
  3. 流量可以從全國各地發起,更加真實的反映用戶的體驗
  4. 全方位的監控壓測指標
  5. 文檔比較完善

當然了雲壓測是一款商業產品,在使用的時候自然還是需要收費的,而且價格還是比較昂貴的~

3.4.2 阿里雲 性能測試 PTS

PTS(Performance Testing Service)是面向所有技術背景人員的雲化測試工具。有別於傳統工具的繁複,PTS以互聯網化的交互,提供性能測試、API調試和監測等多種能力。自研和適配開源的功能都可以輕鬆模擬任意體量的用戶訪問業務的場景,任務隨時發起,免去繁瑣的搭建和維護成本。更是緊密結合監控、流控等兄弟產品提供一站式高可用能力,高效檢驗和管理業務性能。

阿里雲同樣還是支持滲透測試,通過模擬黑客對業務系統進行全面深入的安全測試。

3.4.3 騰訊雲 壓測大師 LM

通過創建虛擬機器人模擬多用戶的併發場景,提供一整套完整的服務器壓測解決方案

4、go-stress-testing go語言實現的壓測工具

4.1 介紹

  • go-stress-testing 是go語言實現的簡單壓測工具,源碼開源、支持二次開發,可以壓測http、webSocket請求,使用協程模擬單個用戶,可以更高效的利用CPU資源。
  • 項目地址 https://github.com/link1st/go-stress-testing

4.2 用法

  • 支持參數:
Usage of ./go_stress_testing_mac:
  -c uint
        併發數 (default 1)
  -d string
        調試模式 (default "false")
  -n uint
        請求總數 (default 1)
  -p string
        curl文件路徑
  -u string
        請求地址
  -v string
        驗證方法 http 支持:statusCode、json webSocket支持:json (default "statusCode")
  • -n 是單個用戶請求的次數,請求總次數 = -c* -n, 這裏考慮的是模擬用戶行爲,所以這個是每個用戶請求的次數
  • 使用示例:
# 查看用法
go run main.go

# 使用請求百度頁面
go run main.go -c 1 -n 100 -u https://www.baidu.com/

# 使用debug模式請求百度頁面
go run main.go -c 1 -n 1 -d true -u https://www.baidu.com/

# 使用 curl文件(文件在curl目錄下) 的方式請求
go run main.go -c 1 -n 1 -p curl/baidu.curl.txt

# 壓測webSocket連接
go run main.go -c 10 -n 10 -u ws://127.0.0.1:8089/acc
  • 使用 curl文件進行壓測

curl是Linux在命令行下的工作的文件傳輸工具,是一款很強大的http命令行工具。

使用curl文件可以壓測使用非GET的請求,支持設置http請求的 method、cookies、header、body等參數

chrome 瀏覽器生成 curl文件,打開開發者模式(快捷鍵F12),如圖所示,生成 curl 在終端執行命令
copy cURL

生成內容粘貼到項目目錄下的curl/baidu.curl.txt文件中,執行下面命令就可以從curl.txt文件中讀取需要壓測的內容進行壓測了

# 使用 curl文件(文件在curl目錄下) 的方式請求
go run main.go -c 1 -n 1 -p curl/baidu.curl.txt

4.3 實現

  • 具體需求可以查看項目源碼
  • 項目目錄結構
|____main.go                      // main函數,獲取命令行參數
|____server                       // 處理程序目錄
| |____dispose.go                 // 壓測啓動,註冊驗證器、啓動統計函數、啓動協程進行壓測
| |____statistics                 // 統計目錄
| | |____statistics.go            // 接收壓測統計結果並處理
| |____golink                     // 建立連接目錄
| | |____http_link.go             // http建立連接
| | |____websocket_link.go        // webSocket建立連接
| |____client                     // 請求數據客戶端目錄
| | |____http_client.go           // http客戶端
| | |____websocket_client.go      // webSocket客戶端
| |____verify                     // 對返回數據校驗目錄
| | |____http_verify.go           // http返回數據校驗
| | |____websokcet_verify.go      // webSocket返回數據校驗
|____heper                        // 通用函數目錄
| |____heper.go                   // 通用函數
|____model                        // 模型目錄
| |____request_model.go           // 請求數據模型
| |____curl_model.go              // curl文件解析
|____vendor                       // 項目依賴目錄

4.4 go-stress-testing 對 Golang web 壓測

這裏使用go-stress-testing對go server進行壓測(部署在同一臺機器上),並統計壓測結果

  • 申請的服務器配置

CPU: 4核 (Intel Xeon(Cascade Lake) Platinum 8269 2.5 GHz/3.2 GHz)

內存: 16G
硬盤: 20G SSD
系統: CentOS 7.6

go version: go1.12.9 linux/amd64

go-stress-testing01

  • go server
package main

import (
    "log"
    "net/http"
)

const (
    httpPort = "8088"
)

func main() {

    runtime.GOMAXPROCS(runtime.NumCPU() - 1)

    hello := func(w http.ResponseWriter, req *http.Request) {
        data := "Hello, World!"

        w.Header().Add("Server", "golang")
        w.Write([]byte(data))

        return
    }

    http.HandleFunc("/", hello)
    err := http.ListenAndServe(":"+httpPort, nil)

    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}
  • go_stress_testing 壓測命令
./go_stress_testing_linux -c 100 -n 10000 -u http://127.0.0.1:8088/
  • 壓測結果
併發數 go_stress_testing QPS
1 6394.86
4 16909.36
10 18456.81
20 19490.50
30 19947.47
50 19922.56
80 19155.33
100 18336.46
200 16813.86

從壓測的結果上看:效果還不錯,壓測QPS有接近2W

5、壓測工具的比較

5.1 比較

- ab locust Jmeter go-stress-testing 雲壓測
實現語言 C Python Java Golang -
UI界面
優勢 使用簡單,上手簡單 支持分佈式、壓測數據支持導出 插件豐富,支持生成HTML報告 項目開源,使用簡單,沒有依賴,支持webSocket壓測 更加真實的模擬用戶,支持更高的壓測力度

5.2 如何選擇壓測工具

這個世界上沒有最好的,只有最適合的,工具千千萬,選擇一款適合你的纔是最重要的

在實際使用中有各種場景,選擇工具的時候就需要考慮這些:

  • 明確你的目的,需要做什麼壓測、壓測的目標是什麼?
  • 使用的工具你是否熟悉,你願意花多大的成本瞭解它?
  • 你是爲了測試還是想了解其中的原理?
  • 工具是否能支持你需要壓測的場景

6、單臺機器100w連接壓測實戰

6.1 說明

之前寫了一篇文章,基於websocket單臺機器支持百萬連接分佈式聊天(IM)系統(不瞭解這個項目可以查看上一篇或搜索一下文章),這裏我們要實現單臺機器支持100W連接的壓測

目標:

  • 單臺機器能保持100W個長連接
  • 機器的CPU、內存、網絡、I/O 狀態都正常

說明:

gowebsocket 分佈式聊天(IM)系統:

  • 之前用戶連接以後有個全員廣播,這裏需要將用戶連接、退出等事件關閉
  • 服務器準備:
由於自己手上沒有自己的服務器,所以需要臨時購買的雲服務器

壓測服務器:

16臺(稍後解釋爲什麼需要16臺機器)

CPU: 2核
內存: 8G
硬盤: 20G
系統: CentOS 7.6

webSocket壓測服務器

被壓測服務:

1臺

CPU: 4核
內存: 32G
硬盤: 20G SSD
系統: CentOS 7.6

webSocket被壓測服務器

6.2 內核優化

  • 修改程序最大打開文件數

被壓測服務器需要保持100W長連接,客戶和服務器端是通過socket通訊的,每個連接需要建立一個socket,程序需要保持100W長連接就需要單個程序能打開100W個文件句柄

# 查看系統默認的值
ulimit -n
# 設置最大打開文件數
ulimit -n 1040000

這裏設置的要超過100W,程序除了有100W連接還有其它資源連接(數據庫、資源等連接),這裏設置爲 104W

centOS 7.6 上述設置不生效,需要手動修改配置文件

vim /etc/security/limits.conf

這裏需要把硬限制和軟限制、root用戶和所有用戶都設置爲 1040000

core 是限制內核文件的大小,這裏設置爲 unlimited

# 添加一下參數
root soft nofile 1040000
root hard nofile 1040000

root soft nofile 1040000
root hard nproc 1040000

root soft core unlimited
root hard core unlimited

* soft nofile 1040000
* hard nofile 1040000

* soft nofile 1040000
* hard nproc 1040000

* soft core unlimited
* hard core unlimited

注意:

/proc/sys/fs/file-max 表示系統級別的能夠打開的文件句柄的數量,不能小於limits中設置的值

如果file-max的值小於limits設置的值會導致系統重啓以後無法登錄

# file-max 設置的值參考
cat /proc/sys/fs/file-max
12553500

修改以後重啓服務器,ulimit -n 查看配置是否生效

6.3 客戶端配置

由於linux端口的範圍是 0~65535(2^16-1)這個和操作系統無關,不管linux是32位的還是64位的

這個數字是由於tcp協議決定的,tcp協議頭部表示端口只有16位,所以最大值只有65535(如果每臺機器多幾個虛擬ip就能突破這個限制)

1024以下是系統保留端口,所以能使用的1024到65535

如果需要100W長連接,每臺機器有 65535-1024 個端口, 100W / (65535-1024) ≈ 15.5,所以這裏需要16臺服務器

  • vim /etc/sysctl.conf 在文件末尾添加
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_mem = 786432 2097152 3145728
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216

配置解釋:

  • ip_local_port_range 表示TCP/UDP協議允許使用的本地端口號 範圍:1024~65000
  • tcp_mem 確定TCP棧應該如何反映內存使用,每個值的單位都是內存頁(通常是4KB)。第一個值是內存使用的下限;第二個值是內存壓力模式開始對緩衝區使用應用壓力的上限;第三個值是內存使用的上限。在這個層次上可以將報文丟棄,從而減少對內存的使用。對於較大的BDP可以增大這些值(注意,其單位是內存頁而不是字節)
  • tcp_rmem 爲自動調優定義socket使用的內存。第一個值是爲socket接收緩衝區分配的最少字節數;第二個值是默認值(該值會被rmem_default覆蓋),緩衝區在系統負載不重的情況下可以增長到這個值;第三個值是接收緩衝區空間的最大字節數(該值會被rmem_max覆蓋)。
  • tcp_wmem 爲自動調優定義socket使用的內存。第一個值是爲socket發送緩衝區分配的最少字節數;第二個值是默認值(該值會被wmem_default覆蓋),緩衝區在系統負載不重的情況下可以增長到這個值;第三個值是發送緩衝區空間的最大字節數(該值會被wmem_max覆蓋)。

6.4 準備

  1. 在被壓測服務器上啓動Server服務(gowebsocket)
  2. 查看被壓測服務器的內網端口
  3. 登錄上16臺壓測服務器,這裏我提前把需要優化的系統做成了鏡像,申請機器的時候就可以直接使用這個鏡像(參數已經調好)

壓測服務器16臺準備

  1. 啓動壓測
 ./go_stress_testing_linux -c 62500 -n 1  -u ws://192.168.0.74:443/acc

62500*16 = 100W 正好可以達到我們的要求

建立連接以後,-n 1發送一個ping的消息給服務器,收到響應以後保持連接不中斷

  1. 通過 gowebsocket服務器的http接口,實時查詢連接數和項目啓動的協程數
  2. 壓測過程中查看系統狀態
# linux 命令
ps      # 查看進程內存、cup使用情況
iostat  # 查看系統IO情況
nload   # 查看網絡流量情況
/proc/pid/status # 查看進程狀態

6.5 壓測數據

  • 壓測以後,查看連接數到100W,然後保持10分鐘觀察系統是否正常
  • 觀察以後,系統運行正常、CPU、內存、I/O 都正常,打開頁面都正常
  • 壓測完成以後的數據

查看goWebSocket連接數統計,可以看到 clientsLen連接數爲100W,goroutine數量2000008個,每個連接兩個goroutine加上項目啓動默認的8個。這裏可以看到連接數滿足了100W

查看goWebSocket連接數統計

從壓測服務上查看連接數是否達到了要求,壓測完成的統計數據併發數爲62500,是每個客戶端連接的數量,總連接數: 62500*16=100W

壓測服務16臺 壓測完成

  • 記錄內存使用情況,分別記錄了1W到100W連接數內存使用情況
連接數 內存
10000 281M
100000 2.7g
200000 5.4g
500000 13.1g
1000000 25.8g

100W連接時的查看內存詳細數據:

cat /proc/pid/status
VmSize: 27133804 kB

27133804/1000000≈27.1 100W連接,佔用了25.8g的內存,粗略計算了一下,一個連接佔用了27.1Kb的內存,由於goWebSocket項目每個用戶連接起了兩個協程處理用戶的讀寫事件,所以內存佔用稍微多一點

如果需要如何減少內存使用可以參考 @Roy11568780 大佬給的解決方案

傳統的golang中是採用的一個goroutine循環read的方法對應每一個socket。實際百萬鏈路場景中這是巨大的資源浪費,優化的原理也不是什麼新東西,golang中一樣也可以使用epoll的,把fd拿到epoll中,檢測到事件然後在協程池裏面去讀就行了,看情況讀寫分別10-20的協程goroutine池應該就足夠了

至此,壓測已經全部完成,單臺機器支持100W連接已經滿足~

7、總結

到這裏壓測總算完成,本次壓測花費16元鉅款。

單臺機器支持100W連接是實測是滿足的,但是實際業務比較複雜,還是需要持續優化~

通過實現介紹什麼是壓測,在什麼情況下需要壓測,如果覺得現有的壓測工具不適用,可以自己實現或者是改造成適合自己的工具。

8、參考文獻

性能測試工具

性能測試常見名詞解釋

性能測試名詞解釋

PV、TPS、QPS是怎麼計算出來的?

超實用壓力測試工具-ab工具

Locust 介紹

Jmeter性能測試 入門

基於websocket單臺機器支持百萬連接分佈式聊天(IM)系統

github 搜:link1st 查看項目 go-stress-testing

https://github.com/link1st/go-stress-testing

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章