Jmeter test plan is working in local mode (single node) but it not working in distributed mode

9/29/2019

I deployed my JMeter setup on k8s with single master pod and a couple of slave pods. If I try to run this test without using remote instance (-R ) than it works fine but with remote instance, it is completing without any execution. I am not getting any error.

Even it also works on the slave node without using -R option. I tried on a slave node just to make sure that my slave node is able to execute it and there is nothing wrong with the setup.

jmeter -Jserver.rmi.ssl.disable=true -n -t /tests/jmeter/GGSPerf_testplan.jmx -j jmeter_tests.log
jmeter -Jserver.rmi.ssl.disable=true -n -t /tests/jmeter/GGSPerf_testplan.jmx -j jmeter_tests.log -R 
XX.XX.XX.XX

But this test plan is working: https://github.com/kaarolch/kubernetes-jmeter/blob/master/examples/simple_test.jmx

My jmeter test plan:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1.1 r1855137">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" 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="User Defined Variables" enabled="true">
    <collectionProp name="Arguments.arguments"/>
  </elementProp>
  <stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
  <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
    <collectionProp name="HeaderManager.headers">
      <elementProp name="" elementType="Header">
        <stringProp name="Header.name">Content-Type</stringProp>
        <stringProp name="Header.value">text/plain</stringProp>
      </elementProp>
    </collectionProp>
  </HeaderManager>
  <hashTree/>
  <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
    <collectionProp name="Arguments.arguments"/>
  </Arguments>
  <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="Loop Controller" enabled="true">
      <boolProp name="LoopController.continue_forever">false</boolProp>
      <stringProp name="LoopController.loops">100</stringProp>
    </elementProp>
    <stringProp name="ThreadGroup.num_threads">8</stringProp>
    <stringProp name="ThreadGroup.ramp_time">4</stringProp>
    <boolProp name="ThreadGroup.scheduler">false</boolProp>
    <stringProp name="ThreadGroup.duration"></stringProp>
    <stringProp name="ThreadGroup.delay"></stringProp>
  </ThreadGroup>
  <hashTree>
    <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
      <collectionProp name="HeaderManager.headers">
        <elementProp name="" elementType="Header">
          <stringProp name="Header.name">Content-Type</stringProp>
          <stringProp name="Header.value">application/json</stringProp>
        </elementProp>
      </collectionProp>
    </HeaderManager>
    <hashTree/>
    <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV Data Set Config" enabled="true">
      <stringProp name="TestPlan.comments">Test configuration</stringProp>
      <stringProp name="filename">${CSVFileName}</stringProp>
      <stringProp name="fileEncoding">${CSVFileEncoding}</stringProp>
      <stringProp name="variableNames">${CSVHeaderVariables}</stringProp>
      <stringProp name="ignoreFirstLine">${CSVIgnoreHeader}</stringProp>
      <stringProp name="delimiter">${CSVDelimeter}</stringProp>
      <stringProp name="quotedData">${CSVAllowQuotedData}</stringProp>
      <stringProp name="recycle">${CSVRecycleOnEOF}</stringProp>
      <stringProp name="stopThread">${CSVStopThreadOnEOF}</stringProp>
      <stringProp name="shareMode">${CSVSharingMode}</stringProp>
    </CSVDataSet>
    <hashTree/>
    <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="AddressGeocodeRequest" enabled="true">
      <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
      <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
        <collectionProp name="Arguments.arguments">
          <elementProp name="" elementType="HTTPArgument">
            <boolProp name="HTTPArgument.always_encode">false</boolProp>
            <stringProp name="Argument.value">I have JSON body here</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
        </collectionProp>
      </elementProp>
      <stringProp name="HTTPSampler.domain">${GGS_ServerName}</stringProp>
      <stringProp name="HTTPSampler.port">${GGS_ServerPort}</stringProp>
      <stringProp name="HTTPSampler.protocol"></stringProp>
      <stringProp name="HTTPSampler.contentEncoding"></stringProp>
      <stringProp name="HTTPSampler.path">${GGS_RequestPath}</stringProp>
      <stringProp name="HTTPSampler.method">POST</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"></stringProp>
      <stringProp name="HTTPSampler.response_timeout"></stringProp>
    </HTTPSamplerProxy>
    <hashTree/>
    <BackendListener guiclass="BackendListenerGui" testclass="BackendListener" testname="Backend Listener" enabled="true">
      <elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
        <collectionProp name="Arguments.arguments">
          <elementProp name="graphiteMetricsSender" elementType="Argument">
            <stringProp name="Argument.name">graphiteMetricsSender</stringProp>
            <stringProp name="Argument.value">org.apache.jmeter.visualizers.backend.graphite.TextGraphiteMetricsSender</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="graphiteHost" elementType="Argument">
            <stringProp name="Argument.name">graphiteHost</stringProp>
            <stringProp name="Argument.value">test-influxdb</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="graphitePort" elementType="Argument">
            <stringProp name="Argument.name">graphitePort</stringProp>
            <stringProp name="Argument.value">2003</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="rootMetricsPrefix" elementType="Argument">
            <stringProp name="Argument.name">rootMetricsPrefix</stringProp>
            <stringProp name="Argument.value">jmeter.</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="summaryOnly" elementType="Argument">
            <stringProp name="Argument.name">summaryOnly</stringProp>
            <stringProp name="Argument.value">true</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="samplersList" elementType="Argument">
            <stringProp name="Argument.name">samplersList</stringProp>
            <stringProp name="Argument.value"></stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="percentiles" elementType="Argument">
            <stringProp name="Argument.name">percentiles</stringProp>
            <stringProp name="Argument.value">90;95;99</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
        </collectionProp>
      </elementProp>
      <stringProp name="classname">org.apache.jmeter.visualizers.backend.graphite.GraphiteBackendListenerClient</stringProp>
    </BackendListener>
    <hashTree/>
  </hashTree>
</hashTree>

There is nothing useful in Logs, no error or stacktrace:

2019-09-30 10:37:36,873 INFO o.a.j.r.RmiUtils: Disabling SSL for RMI as 
server.rmi.ssl.disable is set to 'true'
2019-09-30 10:37:37,294 INFO o.a.j.e.ClientJMeterEngine: sent test to 
10.56.0.27 basedir='tmp'
2019-09-30 10:37:37,294 INFO o.a.j.e.ClientJMeterEngine: Sending properties 
{}
2019-09-30 10:37:37,315 INFO o.a.j.e.ClientJMeterEngine: sent run command to 
10.56.0.27
2019-09-30 10:37:37,315 INFO o.a.j.e.DistributedRunner: Remote engines have 
been started
2019-09-30 10:37:38,055 INFO o.a.j.JMeter: Started remote host:  10.56.0.26 
(1569839858055)
2019-09-30 10:37:38,254 INFO o.a.j.r.Summariser: summary =      0 in 
00:00:00 = ******/s Avg:     0 Min: 9223372036854775807 Max: 
-9223372036854775808 Err:     0 (0.00%)
2019-09-30 10:37:38,255 INFO o.a.j.JMeter: Finished remote host: 10.56.0.26 
(1569839858255)
2019-09-30 10:37:38,613 INFO o.a.j.JMeter: Started remote host:  10.56.0.27 
(1569839858613)
2019-09-30 10:37:38,706 INFO o.a.j.r.Summariser: summary =      0 in 
00:00:00 = ******/s Avg:     0 Min: 9223372036854775807 Max: 
-9223372036854775808 Err:     0 (0.00%)
2019-09-30 10:37:38,707 INFO o.a.j.JMeter: Finished remote host: 10.56.0.27 
(1569839858707)
2019-09-30 10:37:43,260 INFO o.a.j.JMeter: Interrupting RMI Reaper
-- Ajeet
jmeter
jmeter-5.0
jmeter-plugins
kubernetes
performance-testing

1 Answer

9/30/2019

I can see at least one reason for failure: your test plan is not a valid XML file because it's missing these 2 lines at the bottom:

    </hashTree>
</jmeterTestPlan>

Also given you disable secure RMI on the master side you should do the same for all the slaves:

jmeter-server -Jserver.rmi.ssl.disable=true

And finally, pay attention to the IP address of the JMeter slaves, when you start JMeter slave you should see something like:

Created remote object: UnicastServerRef2 [liveRef: [endpoint:XX.XX.XX.XX:1794,objID:[38be521f:16d80bfab94:-7fff, 2395028286451043349]]]

If the IP address is not something you expect, i.e. machine where you run JMeter slave on has multiple network interfaces, you can explicitly specify which one to bind via java.rmi.server.hostname property like:

jmeter-server -Jserver.rmi.ssl.disable=true -Djava.rmi.server.hostname=XX.XX.XX.XX

More information:

-- Dmitri T
Source: StackOverflow