遅くなりましたが皆様あけましておめでとうございます。今年もどうぞ宜しくお願い致します。
さて、今回とあるプロジェクトで 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” を選択します:
そうすると GRPC Request の Sampler が Thread Group に追加されます:
その後、 Proto Root Directory に .proto を保存しているディレクトリを指定し、 “Full Method” の “Listing…” を押すと、指定した 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 より)