JMeter 自定义采样器 - 与多个 runTest 共享相同的连接
JMeter custom sampler - share same connections with multiple runTest
我通过扩展 AbstractJavaSamplerClient 成功创建了自定义采样器。在采样器实现中,我建立了 JMS 连接并将消息发送到队列。这很好用。如果我将我的线程组配置为 100 和 Ramp-up 1,我的采样器将推送 100 条消息。
现在我想做的是在 JMeter 启动时只建立一次连接,然后在每个 运行.
上重复使用相同的连接来发送消息
任何人都可以解释如何在 JMeter 启动时创建连接,然后与采样器共享相同的连接。
注意:我不能使用现有的 JMS 发布器,因为我想根据不同的应用程序事件计算我的响应时间,而不仅仅是计算将消息发布到 JMS 所花费的时间。
提前致谢。
您可以使用testStarted
method 为所有线程初始化连接。请注意,此方法 运行s 一次,在线程被克隆之前,因此在 testStarted
中,您需要一个连接池,然后线程可以从中获取连接池。例如,一个非常原始的连接池将是一个映射,其中包含一些用于键和连接对象的顺序 ID。每个线程将从该池中获取一个连接,基于线程号:
这样简单的池可以初始化为:
@Override
public void testStarted()
{
int maxConnections = getThreadContext().getThreadGroup().getNumThreads();
ConcurrentMap<Integer, Object> connections = new ConcurrentHashMap<Integer, Object>();
for(int i = 0; i < maxConnections; i++)
{
Object connection = //... whatever you need to do to connect
connections.put(new Integer(i), connection);
}
// Put in the context of thread group
JMeterContextService.getContext().getVariables().putObject("MyConnections", connections);
}
(根据您的需要,连接对象可以是更具体的类型)。
以后可以在sample
方法中使用:
// Get connections pool from context
ConcurrentMap<Integer, Object> connections = (ConcurrentHashMap<Integer, Object>) JMeterContextService.getContext().getVariables().getObject("MyConnections");
// Find connection by thread ID, so each thread goes to a different connection
connections.get(getThreadContext().getThreadNum());
在这里,我天真地假设在 运行 时间返回的线程号与我用于连接初始化的初始顺序整数之间存在完美映射。不是最好的假设,可以改进,但它是一个有效的起点。
然后您可以关闭并删除 testEnded method 中的连接。这个方法也是运行一次,所以我们关闭所有连接:
@Override
public void testEnded()
{
for(Entry<Integer, Object> connection : connections.entrySet())
{
connection.close(); // or do whatever you need to close it
connections.remove(connection.getKey());
}
}
或者您可以在所有连接都关闭时调用 connections.clear()
。
披露:我没有直接测试这个答案中的代码,而是使用了过去类似的代码片段,并重新使用它们来回答这个问题。如果您发现任何问题,请随时更新此答案。
我通过扩展 AbstractJavaSamplerClient 成功创建了自定义采样器。在采样器实现中,我建立了 JMS 连接并将消息发送到队列。这很好用。如果我将我的线程组配置为 100 和 Ramp-up 1,我的采样器将推送 100 条消息。
现在我想做的是在 JMeter 启动时只建立一次连接,然后在每个 运行.
上重复使用相同的连接来发送消息任何人都可以解释如何在 JMeter 启动时创建连接,然后与采样器共享相同的连接。
注意:我不能使用现有的 JMS 发布器,因为我想根据不同的应用程序事件计算我的响应时间,而不仅仅是计算将消息发布到 JMS 所花费的时间。
提前致谢。
您可以使用testStarted
method 为所有线程初始化连接。请注意,此方法 运行s 一次,在线程被克隆之前,因此在 testStarted
中,您需要一个连接池,然后线程可以从中获取连接池。例如,一个非常原始的连接池将是一个映射,其中包含一些用于键和连接对象的顺序 ID。每个线程将从该池中获取一个连接,基于线程号:
这样简单的池可以初始化为:
@Override
public void testStarted()
{
int maxConnections = getThreadContext().getThreadGroup().getNumThreads();
ConcurrentMap<Integer, Object> connections = new ConcurrentHashMap<Integer, Object>();
for(int i = 0; i < maxConnections; i++)
{
Object connection = //... whatever you need to do to connect
connections.put(new Integer(i), connection);
}
// Put in the context of thread group
JMeterContextService.getContext().getVariables().putObject("MyConnections", connections);
}
(根据您的需要,连接对象可以是更具体的类型)。
以后可以在sample
方法中使用:
// Get connections pool from context
ConcurrentMap<Integer, Object> connections = (ConcurrentHashMap<Integer, Object>) JMeterContextService.getContext().getVariables().getObject("MyConnections");
// Find connection by thread ID, so each thread goes to a different connection
connections.get(getThreadContext().getThreadNum());
在这里,我天真地假设在 运行 时间返回的线程号与我用于连接初始化的初始顺序整数之间存在完美映射。不是最好的假设,可以改进,但它是一个有效的起点。
然后您可以关闭并删除 testEnded method 中的连接。这个方法也是运行一次,所以我们关闭所有连接:
@Override
public void testEnded()
{
for(Entry<Integer, Object> connection : connections.entrySet())
{
connection.close(); // or do whatever you need to close it
connections.remove(connection.getKey());
}
}
或者您可以在所有连接都关闭时调用 connections.clear()
。
披露:我没有直接测试这个答案中的代码,而是使用了过去类似的代码片段,并重新使用它们来回答这个问题。如果您发现任何问题,请随时更新此答案。