リモート開発メインのソフトウェア開発企業のエンジニアブログです

JMeter gRPC Request で gRPC リクエストを送る方法とハマった点

遅くなりましたが皆様あけましておめでとうございます。今年もどうぞ宜しくお願い致します。

さて、今回とあるプロジェクトで gRPC の API サーバーへの負荷試験をする事になったのですが、以前、中の人が記事を書いた通り、今回もノウハウのある JMeter を使おうと思いました。
執筆時点 (2022 年 1 月) ではデフォルトで JMeter は gRPC のサポートをしていない為、プラグインを使う必要があります。
公式のサイトにも載っている事もあり、今回は JMeter gRPC Request プラグインを使ったので、ハマった点と合わせて軽くご紹介させて頂きます。

環境

  • JMeter 5.4.1
  • openjdk version “14.0.2” 2020-07-14
  • JMeter gRPC Request 1.2.1

プラグインのインストールはとっても簡単で、 JMeter のディレクトリの lib/ext 内に GitHub からダウンロードしたプラグインの jar を入れれば良いだけです。

gRPC リクエストのプロファイルを作成

HTTP リクエスト等同様、 “Thread Group” -> “Add” -> “Sampler” -> “GRPC Request” を選択します:

Apache JMeter より、Thread Group に Sampler を追加する画面

そうすると GRPC Request の Sampler が Thread Group に追加されます:

GRPC Request の設定画面

その後、 Proto Root Directory に .proto を保存しているディレクトリを指定し、 “Full Method” の “Listing…” を押すと、指定した Protocol Buffers からメソッドの一覧を読み出す事ができます:

Protocol Buffers の読み込み

その後、 “Server Name or IP” や “Port” を設定したり、必要であれば本文を JSON で “Send JSON Format With the Request” に指定すれば基本的な設定は完了です。

その他の Thread の設定や入力元データや試験結果の出力先の設定等は HTTP リクエスト等と同様に行う事ができます。

ハマりどころ: Alpine Linux では動かない

今回のワークロードでは Kubernetes を使う事になっていたのでコンテナ化をしたのですが、その際 18-alpine 系列をベースイメージとしたのですが、そうすると正しく負荷試験を行う事ができませんでした:

FROM openjdk:18-jdk-alpine3.15

ARG JMETER_VERSION=5.4.1
ARG JMETER_GRPC_REQUEST_VERSION=1.2.1

RUN cd /tmp && \
    wget https://dlcdn.apache.org/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.zip && \
    unzip apache-jmeter-${JMETER_VERSION}.zip && \
    rm -fr apache-jmeter-${JMETER_VERSION}.zip && \
    mv apache-jmeter-${JMETER_VERSION} /opt/apache-jmeter

RUN wget https://github.com/zalopay-oss/jmeter-grpc-request/releases/download/v${JMETER_GRPC_REQUEST_VERSION}/jmeter-grpc-request-v${JMETER_GRPC_REQUEST_VERSION}.jar -P /opt/apache-jmeter/lib/ext

ENV JMETER_HOME=/opt/apache-jmeter
ENV PATH=$JMETER_HOME/bin:$PATH

WORKDIR /root

ENTRYPOINT ["jmeter"]
# 結果ファイルより。 protoc の実行に失敗している
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect             0.0s
0,0,,500,Exception: Unable to execute protoc binary,Thread Group 1-1,text,false,,46,0,1,1,null,0,0,0

原因としては、リクエスト時に Protocol Buffers のコンパイルを行うのですが、 protoc が glibc に依存している為です。(※)
alpine-pkg-glibc を使うと簡単に glibc を入れる事ができます。 Dockerfile の適当な所に以下を追加します:

ARG GLIBC_VERSION=2.34

RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}-r0/glibc-${GLIBC_VERSION}-r0.apk && \
    apk add glibc-${GLIBC_VERSION}-r0.apk

これで無事動作する様になりました:

timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
nection]",Thread Group 1-1,text,false,,155,0,1,1,null,0,0,0
1642135083009,456,GRPC Request,200,Success,Thread Group 1-1,text,true,,3,0,1,1,null,0,0,0

※ Error running on Alpine (protoc を Java から実行できる OSS ライブラリ “os72/protoc-jar” の Issue より)

← 前の投稿

SQL WINDOW関数を用いた重複レコードの排除

次の投稿 →

PHPの静的メソッド呼び出しと利用について

コメントを残す