Gatling OperatorとPrism Mockで実現する負荷試験

# はじめに
本記事では、Gatling OperatorとPrism Mockを使って負荷試験を実施する方法を記載します。
これらのツールを組み合わせることで、依存するマイクロサービスに影響を与えずに効率的に負荷試験を行うことができます。
ここでは、Prism Mockの設定周りをメインに記載しています。

## Gatling Operatorとは
Gatling Operatorは、ZOZOが開発したKubernetes上で負荷試験を簡単に実施するためのOSSツールです。詳細は以下の記事をご参照ください。

https://techblog.zozo.com/entry/gatling-operator-introduction

## Prism Mockとは
Prism Mockは、OpenAPI仕様に基づき、正常系のexample値を使用してレスポンスを返すモックツールです。モック環境を手軽に構築できるため、負荷試験に最適です。詳細は以下の記事をご覧ください。

https://techblog.zozo.com/entry/prism-in-kubernetes

# 負荷試験構成
今回の例では、zozo-oidc-provider-apiというマイクロサービスに対して負荷試験を実施します。このAPIはzozo-idという別のマイクロサービスに依存していますが、Prism Mockを利用してzozo-idをモック化することで、実サービスへの影響を抑えつつ試験を行うことができます。

以下は試験構成図です。

![負荷試験構成 prism mock.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509379/c11cd1bd-4153-75a3-6191-4d688010a226.png)

# 手順
## Prism Mock作成

https://github.com/gold-kou/prism-in-k8s

上記に記載のセットアップ手順に従って、以下を準備します。

1.`app/openapi.yaml`に対象API(zozo-id)のOpenAPI仕様書を配置

2.`config/params.yaml`に以下内容を定義
```yaml: config/params.yaml
microserviceName: "zozo-id"
microserviceNamespace: "zozo-id"
prismMockSuffix: "-prism-mock"
istioMode: true
```

3.`make run-create`コマンドでモック環境を作成

## VirtualServiceの設定
zozo-oidc-provider-apiからリクエストをルーティングするzozo-idのVirtualServiceとその先のPrism Mock用のVirtualServiceを設定します。

### zozo-idのVirtualService
以下の設定で、zozo-oidc-provider-apiからzozo-idへのリクエストパス`/xxx`(tmp)をPrism Mockに委譲します。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: zozo-id-delegate
spec:
  gateways:
    - mesh
  hosts:
    - zozo-id
  http:
    - name: zozo-id-prism-mock # Loadtest for zozo-oidc-provider-api
      match:
        - uri:
            prefix: /xxx
        - sourceLabels:
            app: zozo-oidc-provider-api
      delegate:
        name: zozo-id-prism-mock
        namespace: zozo-id-prism-mock
    - name: default
      retries:
        attempts: 1
        retryOn: "5xx"
      delegate:
        name: zozo-id
        namespace: zozo-id
```

### Prism MockのVirtualService
次に、Prism MockのVirtualServiceに対象のリクエストパス`/xxx`(tmp)とレイテンシーを設定します。

```yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: zozo-id-prism-mock
  namespace: zozo-id-prism-mock
spec:
  hosts: [] # delegate先のvsになるためhostsは空にする
  http:
  - name: zozo-id-prism-mock
    match:
    - method:
        exact: POST
      uri:
        prefix: /xxx
    fault:
      delay:
        fixedDelay: 33ms
        percentage:
          value: 100
    route:
    - destination:
        host: zozo-id-prism-mock.zozo-id-prism-mock.svc.cluster.local
  - name: default
    route:
    - destination:
        host: zozo-id-prism-mock.zozo-id-prism-mock.svc.cluster.local
```

zozo-idの対象パスのレイテンシー(fault.delay.fixedDelay)は、Datadog APMから確認しています。以下のグラフより、p50値の約33msを使用しています。

![zozo-idのlatency.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509379/bb86341e-58d5-7723-cbd4-cfca5e5c4cc6.png)

# 結果
上記設定をもとにGatling Operatorを使用して実行し、Datadog APMでレスポンス状況を確認しました。Prism Mock部分は比較的想定どおりのレスポンスを返しており、問題なく負荷をかけることができました。

![gatling結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2509379/4a759204-9e62-28f3-af5c-d58e7d36aed3.jpeg)

# まとめ
本記事では、Gatling OperatorとPrism Mockを組み合わせた負荷試験について、主にPrism Mock周りの設定方法を紹介しました。この方法を活用することで、依存するマイクロサービスに影響を与えずに効率的な負荷試験を実現できます。
負荷試験手法の一つとしてお役に立てれば幸いです。