用于测试Websocket应用程序的JMeter自定义Java客户端

时间:2014-02-11 14:00:07

标签: java websocket jmeter

我正在尝试使用JMeter对在云中运行的应用程序进行基准测试。底层协议使用websockets,但是我需要使用一些专有库来进行这些调用。我看了一些JMeter的websocket插件。但不仅仅是测试我想使用JMeter的能力来为我的服务器进行分布式负载生成。我想使用我自己的客户端(用Java编写)来实现对服务器的实际请求。这有可能吗?

1 个答案:

答案 0 :(得分:2)

WebSocket Client API有不同的实现,即Jetty Websocket APIJava API for WebSocket

最近我一直在调查如何使用JMeter Load Testing Cloud Solution测试WebSockets。请参阅下面的概念证明细节。它正在使用JavaSamplerClient API,因此将扩展名打包为.jar并放在JMeter下,Classpath将作为Java Request Sampler提供。

首先,您需要Tyrus - 开源JSR-356实现。 Tyrus需要Java 7,因此请确保使用Java SE 7构建和执行扩展。获取依赖关系的最方便方法是使用以下Apache Maven配置文件

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>blazemeter-websocket</groupId>

<artifactId>blazemeter-websocket</artifactId>

<version>1.0-SNAPSHOT</version>

<dependencies>

<dependency>

<groupId>javax.websocket</groupId>

<artifactId>javax.websocket-client-api</artifactId>

<version>1.0</version>

</dependency>

<dependency>

<groupId>org.glassfish.tyrus</groupId>

<artifactId>tyrus-client</artifactId>

<version>1.1</version>

</dependency>

<dependency>

<groupId>org.glassfish.tyrus</groupId>

<artifactId>tyrus-container-grizzly</artifactId>

<version>1.1</version>

</dependency>

<dependency>

<groupId>javax.json</groupId>

<artifactId>javax.json-api</artifactId>

<version>1.0</version>

</dependency>

<dependency>

<groupId>org.glassfish</groupId>

<artifactId>javax.json</artifactId>

<version>1.0.1</version>

</dependency>

</dependencies>

</project>

目标“mvn依赖:copy-dependencies”的调用会将所有必需的jar下载到/ target / dependency文件夹中。但是你可以继续使用构建,打包等maven插件。

扩展的源代码如下:

package com.blazemeter;

import org.apache.jmeter.config.Arguments;

import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;

import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;

import org.apache.jmeter.samplers.SampleResult;

import org.apache.jorphan.logging.LoggingManager;

import org.apache.log.Logger;

import org.glassfish.tyrus.client.ClientManager;

import javax.websocket.*;

import java.io.IOException;

import java.net.URI;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.TimeUnit;

@ClientEndpoint

public class BlazemeterWebsocketRequest extends AbstractJavaSamplerClient {

private static String ws_uri;

private static String ws_message;

private static String response_message;

private static CountDownLatch latch;

private static final Logger log = LoggingManager.getLoggerForClass();

@Override

public Arguments getDefaultParameters() {

Arguments params = new Arguments();

params.addArgument("URI", "ws://echo.websocket.org");

params.addArgument("Message", "Blazemeter rocks!");

return params;

}

@Override

public void setupTest(JavaSamplerContext context) {

ws_uri = context.getParameter("URI");

ws_message = context.getParameter("Message");

}

@Override

public SampleResult runTest(JavaSamplerContext javaSamplerContext) {

SampleResult rv = new SampleResult();

rv.sampleStart();

latch = new CountDownLatch(1);

ClientManager client = ClientManager.createClient();

try {

client.connectToServer(BlazemeterWebsocketRequest.class, new URI(ws_uri));

latch.await(1L, TimeUnit.SECONDS);

} catch (Throwable e) {

throw new RuntimeException(e);

}

rv.setSuccessful(true);

rv.setResponseMessage(response_message);

rv.setResponseCode("200");

if (response_message != null) {

rv.setResponseData(response_message.getBytes());

}

rv.sampleEnd();

return rv;

}

@OnOpen

public void onOpen(Session session) {

log.info("Connected ... " + session.getId());

try {

session.getBasicRemote().sendText(ws_message);

} catch (IOException e) {

throw new RuntimeException(e);

}

}

@OnMessage

public String onMessage(String message, Session session) {

log.info("Received ... " + message + " on session " + session.getId());

response_message = message;

try {

session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE,""));

} catch (IOException e) {

e.printStackTrace();

}

return response_message;

}

@OnClose

public void onClose(Session session, CloseReason closeReason) {

log.info(String.format("Session %s close because of %s", session.getId(), closeReason));

}

}

希望这有帮助,

d