堪比JMeter的.Net壓測工具 - Crank 入門篇

MASA技術團隊發表於2022-03-08

1. 前言

Crank 是.NET 團隊用來執行基準測試的基準測試基礎架構,包括(但不限於)來自TechEmpower Web 框架基準測試的場景,是2021年.NET Conf 大會上介紹的一項新的專案,其前身是Benchmarks

Crank目標之一是為開發人員提供一種工具,讓他們能夠非常輕鬆地處理效能並衡量潛在的改進。其中一些功能是:

  • 部署和基準測試基於 .NET 或 Docker 容器的多層應用程式

通過指定.Net專案(本地路徑或git遠端倉庫地址),支援直接部署或通過Docker部署應用程式,用於基準測試)

  • 通過Yml配置,不僅僅支援結果儲存在 JSON 、SQL Server 中還支援儲存到csv檔案中以用於圖表

目前有小夥伴已經在提議將支援儲存在es

  • 支援更改自定義應用程式的Franework環境,測試在不同環境下的效能
  • 收集診斷跟蹤資訊

2. 核心組成

Crank由Agent、Controller兩部分組成

Controller是任務的排程者,可以排程負載任務以及輸出結果

Agent是基準代理,任務的實際執行者,接收來自Controller的任務並執行。

3. 安裝

欲先工其善 必先利其器,我們先學習下如何安裝crank,以及如何驗證是否安裝成功

3.1. 準備工作

  1. 安裝 .NET 5.0.

  2. 開啟shell:安裝Crank Controller

asciicast

安裝命令:

dotnet tool update Microsoft.Crank.Controller --version "0.2.0-alpha.21567.1" --global

驗證命令:

crank
  1. 開啟shell: 安裝Crank Agent

asciicast

安裝命令:

dotnet tool update Microsoft.Crank.Agent --version "0.2.0-alpha.21567.1" --global

驗證命令:

crank-agent

3.2. 小結

為方便閱讀、文章中Crank Controller簡稱Crank,Crank Agent簡稱Agent

Agent以及Crank需要根據實際情況安裝,可分以下幾種情況:

  • 只是為了學習Crank,沒有單獨的測試環境,則需要分別安裝Agent、Controller

  • Agent有單獨提供測試環境,則本地不需要安裝Agent,只安裝Controller即可

  • Agent有單獨提供測試環境,且壓測任務由ci來觸發執行,則本地不需要安裝任何配置,通過構建ci任務完成壓力計劃即可

開啟shell:檢視Agent、Controller版本

dotnet tool list -g

4. 基礎知識

4.1. variables: 引數

variables分為區域性引數與全域性引數兩種型別,在根節點的為全域性引數,在其他節點下的是區域性引數。

例:

hello.benchmarks.yml > scenarios > hello-load > variables節點下的serverPort以及path以及profiles>local>variables節點下的serverAddress是區域性引數

scenarios:
  hello:
    application:
      job: server
    load:
      job: bombardier
      variables:
        serverPort: 5000
        path: /

profiles:
  local:
    variables:
      serverAddress: localhost

bombardier.yml > variables > headers為全域性引數

variables:
  headers:
    none: ''
    plaintext: '--header "Accept: text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7" --header "Connection: keep-alive"'
    html: '--header "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" --header "Connection: keep-alive"'
    json: '--header "Accept: application/json,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7" --header "Connection: keep-alive"'
    connectionclose: '--header "Connection: close"'
    ---------------------------------------------------------------------

4.2. profiles: 配置

profiles其實就是配置檔案資訊,profiles允許被多次使用,這點在可以在文件中找到對應介紹

Usage: crank [options]

Options:
  -?|-h|--help                       Show help information

  These options are not specific to a Job

  ----------------------------------------------------------------------
  --profile <profile>                Profiles to apply. Can be used multiple times.

命名規則: 建議 *.profiles.yml

4.3. jobs: 任務

將我們要做的事定義為一個job。方便之後重用。此處的事指的是一類事,而不是指特定的某件事。

例如:微軟內建定義的bombardier就是一個job,這個job是通過bombardier對其進行基準測試,並將結果記錄並輸出,而具體針對哪個介面進行基準測試其實並不關心。

job根據應用程式源有分為遠端、本地兩種。

本地源:

jobs:
  server: #任務名稱,可根據任務作用自行命名
    source: #任務源
      localFolder: ../hello 
      project: hello.csproj #要構建的 .NET 專案的檔名
    readyStateText: Application started. #控制檯中通知伺服器它已啟動的文字

本地源localFolder針對當前執行crank --config執行命令所在的相對路徑即可,任務開始後會將本地的專案傳送到agent後再執行任務。

遠端源

jobs:
  server:
    source:
      repository: https://github.com/dotnet/crank
      branchOrCommit: main #遠端源執行任務的分支
      project: samples/hello/hello.csproj #要構建的 .NET 專案的檔名,格式:相對根的相對路徑+專案名.csproj
    readyStateText: Application started.

遠端源會將倉庫資訊傳送到Agent,Agent會先將倉庫下載下來並切換到指定的分支後再執行構建任務啟動專案

4.4. scenarios: 場景

job關心的是一類事,而特定的事情並不關心,那具體的事是誰比較關心呢,沒錯那就是場景,也就是scenarios,scenarios通過多個job來完成對指定場景的基準測試,做的是具體任務的編排

4.5. imports: 匯入

imports為我們提供了yml重用的可能,因為有imports的支援,我們才可以將公共的yml提取到一個單獨的yml中,通過imports將使用到的yml匯入即可,與js、css的匯入有異曲同工之妙

4.6. 小結

在crank中,variables、profiles都不是必須的,但因為它們的存在,才使得我們可以以物件導向的思想開發,可以通過新增變數或指定配置完成基準測試,這塊後面的實戰中會有詳細解釋

5. 入門

經過之前的學習,我們對crank的基本配置也有了一定的瞭解,那接下來的時間,我們先試著學習下官方已經給我們準備好的Sample,下面的教程也會詳細講解一下各個配置的作用,希望能通過下面的學習瞭解到Crank的工作基本原理

5.1. 啟動Agent

asciicast

crank-agent --dotnethome "/home/{your-account}/dotnet"
5.1.0.1. 啟動Agent並指定dotnet環境
  • 格式:crank-agent –dotnethome "dotnet安裝地址"

  • crank-agent --dotnethome "C:\Program Files\dotnet" (windows)

  • crank-agent --dotnethome "/usr/share/dotnet" (Linux)

  • 在啟動agent時,強烈建議大家增加dotnethome 配置,為agent執行指定環境,以免執行任務時由於環境問題而卡在install sdk這裡

  • 因演示機器本地dotnet的使用的是安裝路徑為/home/gushoudao/dotnet,所以視訊中執行的命令有所不同,這塊還需要根據本地的實際情況自行調整路徑即可 (因視訊錄製原因,在錄製結束後會停止agent,我們真實使用中啟動後不需要退出,一旦退出agent,就無法執行任務)

5.1.0.2. 啟動Agent並指定不清理臨時檔案
  • crank-agen --no-cleanup (指定不清理臨時檔案)

預設agent執行任務結束後會刪除當前任務執行過程中產生的臨時檔案

5.1.0.3. 啟動Agent並指定構建任務的最大持續時間
  • crank-agent --build-timeout

預設構建任務的最大持續時間為10 minutes

更多配置點選檢視

5.2. 新建hello.benchmarks.yml配置

配置檔案原始碼來自hello.benchmarks.yml

imports:
  - https://raw.githubusercontent.com/doddgu/crank/sample/src/Microsoft.Crank.Jobs.Bombardier/bombardier.yml

jobs:
  server:
    source:
      repository: https://github.com/doddgu/crank
      branchOrCommit: sample
      project: samples/hello/hello.csproj
    readyStateText: Application started.

scenarios:
  hello:
    application:
      job: server
    load:
      job: bombardier
      variables:
        serverPort: 5000
        path: /

profiles:
  local:
    variables:
      serverAddress: localhost
    jobs: 
      application:
        endpoints: 
          - http://localhost:5010
      load:
        endpoints: 
          - http://localhost:5010

5.3. 啟動任務

啟動agent(開啟放在一邊):

crank-agent --dotnethome "/usr/share/dotnet"

啟動任務(另起一個新的Shell):

git clone https://github.com/doddgu/crank.git
cd crank
git checkout sample
crank --config ./samples/hello/hello.original.benchmarks.yml --scenario hello --load.framework net5.0 --application.framework net5.0

然後我們等待片刻會輸出以下結果

crank-agent:

asciicast

crank:

asciicast

| load                  |                |
| --------------------- | -------------- |
| CPU Usage (%)         | 39             |  CPU使用率
| Cores usage (%)       | 631            |  多核CPU使用率
| Working Set (MB)      | 35             |  記憶體使用率
| Private Memory (MB)   | 35             |  程式使用的私有記憶體量
| Build Time (ms)       | 4,853          |  構建應用程式需要多長時間(毫秒)
| Start Time (ms)       | 386            |  啟動應用程式需要多長時間(毫秒)
| Published Size (KB)   | 66,731         |  已釋出應用程式的大小 (KB)
| .NET Core SDK Version | 5.0.403        |  .Net Core SDK 版本
| ASP.NET Core Version  | 5.0.12+0bc3c37 |  .Net Core版本
| .NET Runtime Version  | 5.0.12+7211aa0 |  .Net執行時版本
| First Request (ms)    | 172            |  第一個請求耗時(這裡請求是Get)
| Requests              | 2,086,594      |  總髮送請求數
| Bad responses         | 0              |  糟糕請求數(響應狀態碼不是2**也不是3**)
| Mean latency (us)     | 1,833          |  平均延遲時間
| Max latency (us)      | 89,001         |  最大延遲時間
| Requests/sec          | 138,067        |  每秒支援請求數
| Requests/sec (max)    | 255,442        |  每秒最大支援請求數

當你能輸出以上資訊的時候,證明了你已經成功跑通了整個流程

在上面我們可以很清楚的看到場景hello下的測試結果,其中包含CPU使用率、多核CPU的使用率、記憶體使用率以及每秒執行的請求數等等指標

在這一刻是不是突然覺得這個crank挺強大的,雖然還不清楚具體是咋做到的,但是真的很贊!!在這一刻是不是對它來了興趣,想知道它到底可以做什麼,為什麼可以輸出以上的結果?

6. 結尾

為確保後續不會因更新導致按照文件操作不可用,原始碼從官方源Fork了一份,其中絕大多數來自官方提供的Sample、部分檔案為了更好的滿足個人習慣,會在一定程度上進行調整。

原始碼地址:https://github.com/doddgu/crank/tree/sample

參考連結:

開源地址

MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks

MASA.Contrib:https://github.com/masastack/MASA.Contrib

MASA.Utils:https://github.com/masastack/MASA.Utils

MASA.EShop:https://github.com/masalabs/MASA.EShop

MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

如果你對我們的 MASA Framework 感興趣,無論是程式碼貢獻、使用、提 Issue,歡迎聯絡我們

16373211753064.png

相關文章