0
votes

I have a test plan with the mix of normal HTTP samplers and JSR223 samplers. JSR223 I use to execute requests via protobuf protocol and HTTP samplers for simple GET/POST requests.

During a test via SSL protocol, we have discovered a huge load on the Nginx due big amount of SSL handshakes provided by JSR223 samplers. The problem was that I created a new HTTPClient in every request:

CloseableHttpClient client = HttpClients.createDefault();

I fixed it with creation only one instance of this client on initial stage and reusage of it in every JSR223 sampler:

CloseableHttpClient client = vars.getObject("client");

So, now we have the situation when every thread is using two HTTPClients (one is using by HTTPSampler, one by JSR223). And the question is there any way to get the HTTPClient from the HTTPSampler to use it further in JSR223 to avoid double handshakes and so on.

Looks like HTTPSamplers are transferring savedClient between each other during a test.

1

1 Answers

1
votes

Unfortunately there is no "good" way of doing this so you way seems to be correct.

Theoretically you can get the access to the same HTTPClient instance using Java Reflection API, but remember, any time you work around JMeter limitation using Reflection somewhere somehow a kitten dies.

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl;

import org.apache.jmeter.samplers.SampleResult;

import java.lang.reflect.Field;
import java.lang.reflect.Method;


Field samplerImpl = sampler.getClass().getDeclaredField("impl");
samplerImpl.setAccessible(true);
HTTPHC4Impl impl = ((HTTPHC4Impl) samplerImpl.get(sampler));
Method method = HTTPHC4Impl.class.getDeclaredMethod("setupClient", URL.class, SampleResult.class);
method.setAccessible(true);
URL url = new URL("http://example.com");
HttpClient client = (HttpClient) method.invoke(impl, url, new SampleResult());
HttpGet get = new HttpGet();
get.setURI(url.toURI());
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
log.info("******************* Response *************************");
log.info(EntityUtils.toString(entity));

Demo:

JMeter get HTTPCLient

And I would recommend switching to Groovy language if you are conducting high loads via scripting, check out Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! for some investigations and benchmarks.