designetwork

ネットワークを軸としたIT技術メモ

JMeter Dashboard Report グラフの粒度を変更する

f:id:daichi703n:20190203172326p:plain

Apache JMeterはWebシステム等のシナリオ試験、性能試験、負荷試験等で広く使用されている。テスト結果からレポート・ダッシュボードを生成することもでき、結果報告書等にも利用できる。

標準で出力されるグラフは1分単位で詳細が把握できないため、グラフの粒度(granularity)を変更して詳細を確認できるようにする。

機能概要についてはドキュメントの通り。

テスト実行からダッシュボード・レポート生成

Apache JMeterのインストール方法は割愛する。今回の試験環境はMacでオフィシャルからtgzをダウンロードし解凍したものを使用している。(brew install jmeterではなく)

テスト対象はシンプルなWeb+APサーバで、PHPでやや負荷がかかるようにしている。

テストケース

今回は単純にスループット(TPS)を増加させていったときの遅延の増加を測定する。

スループットの調整方法は各種紹介されているが、今回はループ回数無制限で一定時間実行するようにし、また各ループの間に1秒の定数タイマーを設定し、スレッド数≒リクエスト/秒となるようにする。限界測定の観点では上限は十分に多ければ問題なく、明確なターゲットスループットがある場合は定数スループットタイマーを使用した方が良い。

f:id:daichi703n:20190203154109p:plain

JMXファイルは以下の通り。

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.0 r1840935">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Simple Latency" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="ユーザー定義変数" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="ループコントローラ" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <intProp name="LoopController.loops">-1</intProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">100</stringProp>
        <stringProp name="ThreadGroup.ramp_time">180</stringProp>
        <boolProp name="ThreadGroup.scheduler">true</boolProp>
        <stringProp name="ThreadGroup.duration">300</stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
            <collectionProp name="Arguments.arguments"/>
          </elementProp>
          <stringProp name="HTTPSampler.domain">hello.designet.local</stringProp>
          <stringProp name="HTTPSampler.port"></stringProp>
          <stringProp name="HTTPSampler.protocol">http</stringProp>
          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
          <stringProp name="HTTPSampler.path"></stringProp>
          <stringProp name="HTTPSampler.method">GET</stringProp>
          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
          <stringProp name="HTTPSampler.connect_timeout">1000</stringProp>
          <stringProp name="HTTPSampler.response_timeout">1000</stringProp>
        </HTTPSamplerProxy>
        <hashTree/>
        <ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
          <stringProp name="ConstantTimer.delay">1000</stringProp>
        </ConstantTimer>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

テスト実行・レポート生成

ダッシュボード・レポートを生成するためには、GUIではなく、CLIからJMeterを実行する必要がある。

GUIで保存したテストをCLIから実行する。

$ apache-jmeter-5.0/bin/jmeter -n -t Simple-latency.jmx -l log.jtl

ダッシュボード・レポートを生成する。

$ apache-jmeter-5.0/bin/jmeter -g log.jtl -o dashboard

ダッシュボードを参照する。

$ open dashboard/index.html

f:id:daichi703n:20190203160957p:plain

グラフの粒度(granularity)を変更する

デフォルトだと、レポートで生成されるグラフは以下のように、1分間隔となっている。Over Time > Active Threads Over Time を例とする。

f:id:daichi703n:20190203165039p:plain

一見すると、時間の経過(スレッド数・TPSの増加)に伴い遅延(Latency)が単純増加するように見えるが、これは1分間隔で丸められていることによる誤差である。

グラフの粒度を10秒間隔に変更して再度ダッシュボードを生成する。粒度はJMeteruser.propertiesjmeter.reportgenerator.overall_granularityを変更することによる調整できる。

$ vi apache-jmeter-5.0/bin/user.properties
---
#jmeter.reportgenerator.overall_granularity=60000
↓
jmeter.reportgenerator.overall_granularity=10000

パラメータ変更後は改めてダッシュボードを生成する。log.jtlはそのままでOK。集計時点でパラメータが適用される。

$ apache-jmeter-5.0/bin/jmeter -g log.jtl -o dashboard_10s

グラフの粒度・分解能が上がって細かくなり、Over Time > Active Threads Over Timeと並べるとどこから遅延が大きくなってくるかが分かる。スケールも変わっている。

f:id:daichi703n:20190203165030p:plain

f:id:daichi703n:20190203165022p:plain

調整可能なパラメータはこちらの通り。

https://jmeter.apache.org/usermanual/generating-dashboard.html

まとめ - JMeter Dashboard Report グラフの粒度を変更する

JMeteruser.propertiesjmeter.reportgenerator.overall_granularityを変更することによって、Dashboard Report グラフの粒度を変更できた。

$ vi apache-jmeter-5.0/bin/user.properties
---
#jmeter.reportgenerator.overall_granularity=60000
↓
jmeter.reportgenerator.overall_granularity=10000