ghzでgRPCの負荷試験(Benchmark Test)を行います hz

## はじめに
gRPCの負荷試験の為に[ghz](https://github.com/bojand/ghz)というツールを使おうと思うのですが、「hz」の意味がわからず読み方がわかりません。😊
ちょっと洋式トイレにも見えます。

## 基本的な使い方

### インストール方法

githubのどトップに書いてあるので説明するまでも感がありますが、一応。
MACerなのでbrewでインストールしております。

``` sh
brew install ghz
```

### 実行コマンド

``` sh
ghz --config=./config.json
```

### configファイルの中身

``` json:config.json
{
  "name": "Otsuka Test",
  "call": "akame.Linebot.ReplyMessage",
  "host": "0.0.0.0:50051",
  "total": 15000,
  "concurrency": 300,
  "connections": 300,
  "rps": 3000,
  "data": {
    "line_id": "azusa",
    "text": "{{randomString 10 }}",
    "nonce": "hogehoge"
  },
  "format": "html",
  "output": "report.html",
  "insecure": true,
  "load-schedule": "const",
  "load-start": 0,
  "load-end": 0,
  "load-step": 0,
  "load-step-duration": 0,
  "load-max-duration": 0,
  "concurrency-schedule": "const",
  "concurrency-start": 1,
  "concurrency-end": 0,
  "concurrency-step": 0,
  "concurrency-step-duration": 0,
  "concurrency-max-duration": 0,
  "timeout": "20s",
  "binary": false
}
```

### 今回使用した彼女 (gRPCアプリケーション)
https://qiita.com/taisei_otsuka/items/87adaf5f8ed19a8549c5


## configの中身を解説

**name**
テストの名称です。(一応解説)

**call**
コールするメソッド名です。
※ reflectionを使用していない場合、追加で--protoオプションを指定する必要があります。

**host**
(略)

**total**
リクエストの合計数です。
例えば1秒3,000リクエストで5秒間負荷をかけたい場合、合計は15,000となります。

**concurrency**
並行(同時)実行数です。

※ 同時接続数ではありません。

**connections**
gRPCの同時接続数を指定できます。
concurrencyオプションの数を超えることは出来ません。

**rps**
秒間リクエストの数です。
rps=10, total=100
だと1秒10リクエストなので、負荷テストが完了するまで10秒かかる計算となります。

**data**
gRPCで送るbody部分です。

```{{randomString 10 }}```の記述は10桁(指定した桁)でランダムな文字列を生成してくれます。
他にも色々便利なParamがありますが割愛します。

データを固定データではなく、いくつかのパターンに分割してリクエストしたいという場合があると思います。
そういう時は、[]配列形式 ↓ でデータを飛ばしてあげると動作します。

```json
[
  {
    "line_id": "azusa",
    "text": "{{randomString 10 }}",
    "nonce": "hogehoge"
  },
  {
    "line_id": "yui",
    "text": "{{randomString 10 }}",
    "nonce": "fugafuga"
  }
]
```

なので

```json
[
  {
    "line_id": "azusa",
    "text": "{{randomString 10 }}",
    "nonce": "hogehoge"
  }
]
```

↑これと
↓これは同義となります。

```json
{
  "line_id": "azusa",
  "text": "{{randomString 10 }}",
  "nonce": "hogehoge"
}
```

**format**
reportの形式を選べます。
指定がない場合コンソールに出力されます。

形式の一覧は以下です。

```csv, json, pretty, html, influx-summary, influx-details, prometheus```

influxDBを指定できるため```influxDB => Grafana```や、```prometheus => Grafana```の接続も可能となります。

HTMLレポートはこんな感じで表示されます。↓

![スクリーンショット 2021-11-29 10.53.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170923/5a489aff-115e-5c73-00a8-1919fdff8a5a.png)

**load-\*\*\*オプション**
rpsを時間経過ともに増減できるオプションです。
load-scheduleはconst・step・lineの何れかから選べます。
load-scheduleの種別ごとの設定は以下です。

- const  
rpsで指定した秒間リクエストがそのまま実行されます。
- step  
startからendにかけてstep-durationで設定した時間ごとにstep数分rpsが増加or減少します。  
max-durationはendに訪れる前にこの時間を経過すると、その時点でのrpsで負荷テストを続行し、それ以上rpsは増減しません。
- line  
startからendにかけて1秒ごとにstep数分rpsが増減します。

**concurrency-\*\*\*オプション**
並行(同時)実行数を時間経過ともに増減できるオプションです。
concurrency-scheduleはconst・step・lineの何れかから選べます。
concurrency-scheduleの種別ごとの設定は以下です。

- const  
concurrencyで指定した秒間リクエストがそのまま実行されます。
- step  
startからendにかけてstep-durationで設定した時間ごとにstep数分concurrencyが増加or減少します。  
max-durationはendに訪れる前にこの時間を経過すると、その時点でのconcurrencyで負荷テストを続行し、それ以上concurrencyは増減しません。
- line  
startからendにかけて1秒ごとにstep数分concurrencyが増減します。

## あとがき
いっぱいまとめて、疲れたので今日はいいお肉でも食べたいなと思います。

## 採用PR

gRPCやマイクロサービス化・二次元コンテンツに興味がある、もしくはチャレンジしてみたいという方は是非一緒に働きましょう！

https://vivion.page.link/job

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/2000f749-3e82-7a47-b1c4-4444e237f79c.png" width=45%>