从HTTPSampler获取HTTPClient以在Beanshell

时间:2016-11-11 11:38:01

标签: java jmeter

我有一个测试计划,包含普通HTTP采样器和JSR223采样器的混合。 JSR223我用来通过protobuf协议和HTTP采样器执行请求,以获得简单的GET / POST请求。

在通过SSL协议进行的测试中,由于JSR223采样器提供了大量的SSL握手,我们发现了Nginx上的巨大负载。问题是我在每个请求中都创建了一个新的HTTPClient:

CloseableHttpClient client = HttpClients.createDefault();

我修复了它,只在初始阶段创建了这个客户端的一个实例,并在每个JSR223采样器中重新使用它:

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

所以,现在我们遇到的情况是每个线程都使用两个HTTPClient(一个是由HTTPSampler使用,一个是由JSR223使用)。问题是有没有办法让HTTPSampler的HTTPClient在JSR223中进一步使用它来避免双重握手等等。

看起来HTTPSamplers在测试期间正在彼此之间传输savedClient。

1 个答案:

答案 0 :(得分:1)

不幸的是,没有好的"这样做的方式让你的方式似乎是正确的。

理论上你可以使用Java Reflection API访问同一个HTTPClient实例,但是请记住,每当你使用Reflection在某处解决JMeter限制时某个小猫就会死掉。

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));

演示:

JMeter get HTTPCLient

如果您通过脚本执行高负载,我建议您切换到Groovy语言,查看Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For!进行一些调查和基准测试。