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

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

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

目錄

  • 一、項目說明python

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

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

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

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

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

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

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

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

一、項目說明

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.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.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

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

四、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.1 比較

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

5.2 如何選擇壓測工具

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

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

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

六、單臺機器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鏈接已經知足~

七、總結

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

單臺機器支持100W鏈接是實測是知足的,可是實際業務比較複雜,仍是須要持續優化~

經過實現介紹什麼是壓測,在什麼狀況下須要壓測,若是以爲現有的壓測工具不適用,能夠本身實現或者是改形成適合本身的工具。

八、參考文獻

性能測試工具

性能測試常見名詞解釋

性能測試名詞解釋

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

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

Locust 介紹

Jmeter性能測試 入門

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

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

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

相關文章
相關標籤/搜索