使用Jmeter压测Hprose for dotnet or java
前言
1.目标
项目组想对.Net平台的webapi和基于RPC协议的hprose做一个性能的对比。
2.问题:
Postman没有压测功能;LoadRunner太笨重,费钱且学习成本大,且不支持win10家庭版;其他的测试工具网上文档太少,担心出了问题没办法自己解决,因此选用了Jmeter。Jmeter是纯java脚本,查看了一下其插件库,没有类似于将C#脚本转化为java的插件在vs2019中有Jmeter的Nuget包,但没有使用示例,只有一个github网址,其readme文档没什么内容,wiki百科里也没有说明;vs2019扩展工具里有Jmeter Test Explorer但还是不知道怎么用,不好意思真的是废物。
解决方案
1.用idea写一个hprose-server的java脚本,作为hprose的服务端。
2.用idea写一个hprose-client的java脚本,作为hprose的客户端。
3.hprose是一个多语言跨平台基于RPC协议的高性能远程调用服务框架,因此理论上可以使用vs2019来写hprose-server的C#脚本,即hprose for dotnet。在上两步尝试如果可行的情况下,书写C#脚本的服务端,然后使用步骤2的java脚本的客户端去调用,当然可能语法上有一点点需要修改。
4.将hprose-client的java脚本稍作修改,引入jar包,实现jmeter里jar包的类。
5.将hprose-client的java脚本在idea里打成jar包封装,然后装进jmeter目录文件夹lib\ext内。
6.重启Jmeter,使用java请求和查看结果树就可以成功实现。
具体实现步骤
1. 写java脚本的hprose-server。
1.1建立简单的maven项目,next
1.2初始化项目
在pom.xml里引入hprose-java的依赖,如图
<dependencies>
<dependency>
<groupId>org.hprose</groupId>
<artifactId>hprose-java</artifactId>
<version>2.0.38</version>
</dependency>
</dependencies>
新建java类,命名随便,这里命名为TCPHelloServer,写他。
import hprose.server.HproseTcpServer;
public class TCPHelloServer {
public static String hello(String name) {
return "Hello " + name + "!";
}
public static void main(String[] args) throws Exception {
HproseTcpServer server = new HproseTcpServer("tcp://localhost:4322");
server.add("hello", TCPHelloServer.class);
server.start();
System.out.println("START");
System.in.read();
server.stop();
System.out.println("STOP");
}
}
1.3点击小绿箭头运行起来看看。
2.写java脚本的hprose-client。
2.1建立简单的maven项目,next
2.2初始化项目
在pom.xml里引入hprose-java的依赖,如图
<dependencies>
<dependency>
<groupId>org.hprose</groupId>
<artifactId>hprose-java</artifactId>
<version>2.0.38</version>
</dependency>
</dependencies>
新建java类,随便命名,这里命名为TCPHelloClient,写他。
import hprose.client.HproseTcpClient;
interface IHello {
String hello(String name);
}
public class TCPHelloClient {
public static void main(String[] args) throws Throwable {
System.out.println("START");
HproseTcpClient client = new HproseTcpClient("tcp://localhost:4322");
IHello helloClient = client.useService(IHello.class);
System.out.println(helloClient.hello("World"));
System.out.println("END");
}
}
2.3点击小绿箭头运行起来看看。nice~
3.写C#脚本的hprose-server,用java脚本的hprose-client调用,尝试是否可行。
3.1打开vs2019建立简单的控制台程序。
3.2hprose for dot net环境配置
工具-Nuget包-浏览(全装上嘻嘻) 不知道在哪里找“Hprose"的dll文件,我这里还添加了一个引用,师姐直接给我的,就是这个dll文件。
3.3编写类并测试类
写一个Hello类,封装有一个测试方法。在入口函数里调用该类,完成server的搭建。测试运行
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hprose.Server;
namespace Hprose_Server_csdn
{
class Program
{
static void Main(string[] args)
{
HproseHttpListenerServer server = new HproseHttpListenerServer("http://localhost:2020/");
server.GlobalMethods.AddInstanceMethods(new Hello());
server.Start();
Console.WriteLine("server-start");
Console.ReadKey();
server.Stop();
}
}
public class Hello
{
public string sayHello(string input)
{
return "hello" + input + "!";
}
}
}
成功
3.4对java-hproseclient略作修改,调用C#-hproseserver。
3.4.1修改java-hproseclient的代码,其中被注释掉的是之前写的,未被注释的是修改的时候添加的。
import hprose.client.HproseHttpClient;
import hprose.client.HproseTcpClient;
interface IHello {
String hello(String name);
}
interface Hello {
String sayHello(String input) ;
}
public class TCPHelloClient {
public static void main(String[] args) throws Throwable {
// System.out.println("START");
// HproseTcpClient client = new HproseTcpClient("tcp://localhost:4322");
// IHello helloClient = client.useService(IHello.class);
// System.out.println(helloClient.hello("World"));
// System.out.println("END");
System.out.println("START");
HproseHttpClient client = new HproseHttpClient("http://localhost:2020/");
Hello hello = client.useService(Hello.class);
String s = hello.sayHello("linjianshu");
System.out.println(s);
System.out.println("END");
}
}
3.4.2运行C#-hproseServer,运行java-hproseClient看看是否成功调用,ps:可以在服务器端方法体内打个断点看看是否跳进断点里来。
成功噜
4.将hprose-client的java脚本稍作修改,引入jar包,实现jmeter里jar包的类。
既已实现第三步,剩下的就很快了。要实现jmeter识别并编译jar包,需要引入jmeter里的两个jar包并实现。
4.1向java-hproseClient引入jmeter的jar包
从Jmeter的安装目录lib/ext中拷贝两个文件ApacheJMeter_core.jar和ApacheJMeter_java.jar到TestNumber项目中,然后引入这两个JAR包。点击Project Structure --Modules --Dependencies --+ – JARs or directories 打开jmeter存放地址,寻找两个jar包引入。OK-- Apply – OK 让原来的TCPHelloClient类继承引入jar包中的AbstractJavaSamplerClient抽象类,并实现missing methods(alt+enter万能键)(PS:return 的值这里先定义为null , 后面需要修改) 将main方法里的有效代码移到runTest方法体里,注释掉整个main方法
import hprose.client.HproseHttpClient;
import hprose.client.HproseTcpClient;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
interface IHello {
String hello(String name);
}
interface Hello {
String sayHello(String input) ;
}
public class TCPHelloClient extends AbstractJavaSamplerClient {
// public static void main(String[] args) throws Throwable {
// System.out.println("START");
// HproseTcpClient client = new HproseTcpClient("tcp://localhost:4322");
// IHello helloClient = client.useService(IHello.class);
// System.out.println(helloClient.hello("World"));
// System.out.println("END");
//
// }
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
System.out.println("START");
HproseHttpClient client = new HproseHttpClient("http://localhost:2020/");
Hello hello = client.useService(Hello.class);
String s = hello.sayHello("linjianshu");
System.out.println(s);
System.out.println("END");
return null;
}
}
理论上只会实现一个方法,但这个方法在测试的时候只能在jmeter控制台输出,与测试目的相去甚远,因此还需要再写其他3个方法。 setupTest方法初始化、getDefaultParameters允许jmeter编译后传入参数、teardownTest方法测试结束方法形似释放进程滴。这里贴出的代码我还没全部理解透,先放着不影响程序执行。(ps:现在是两天后编辑此篇文章的我,我已经理解一点啦,请有需要的小伙伴移步我的下一篇压测实例,在那将以一个学生crud压测实例做示范,传入随机参数sno来做压测嘻)
import hprose.client.HproseHttpClient;
import hprose.client.HproseTcpClient;
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;
interface IHello {
String hello(String name);
}
interface Hello {
String sayHello(String input) ;
}
public class TCPHelloClient extends AbstractJavaSamplerClient {
// public static void main(String[] args) throws Throwable {
// System.out.println("START");
// HproseTcpClient client = new HproseTcpClient("tcp://localhost:4322");
// IHello helloClient = client.useService(IHello.class);
// System.out.println(helloClient.hello("World"));
// System.out.println("END");
//
// }
private SampleResult results;
private String inNum;
private String resultNum;
public TCPHelloClient() {
}
/**
* 初始化方法,初始化性能测试时的每个线程
* 实际运行时每个线程仅执行一次,在测试方法运行前执行,类似于LoadRunner中的init方法
*/
public void setupTest(JavaSamplerContext jsc) {
this.results = new SampleResult();
this.inNum = jsc.getParameter("inNum", "");
this.resultNum = jsc.getParameter("resultNum11", "");
if (this.inNum != null && this.inNum.length() > 0) {
this.results.setSamplerData(this.inNum);
}
if (this.resultNum != null && this.resultNum.length() > 0) {
this.results.setSamplerData(this.resultNum);
}
}
/**
* 设置传入参数
* 可以设置多个,已设置的参数会显示到Jmeter参数列表中
*/
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("inNum", "");
params.addArgument("input", "ljs");
return params;
}
/**
* 性能测试时的线程运行体
* 测试执行的循环体,根据线程数和循环次数的不同可执行多次,类似于Loadrunner中的Action方法
*/
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
System.out.println("START");
//计时器启动
results.sampleStart();
HproseHttpClient client = new HproseHttpClient("http://localhost:2020/");
Hello hello = client.useService(Hello.class);
String s = hello.sayHello("linjianshu");
//计时器终止
results.sampleEnd();
//请求表示true则成功
//results.setSuccessful(true);
System.out.println(s);
System.out.println("END");
this.results.setResponseData(s,null);
return this.results;
}
/**
* 测试结束方法,结束测试中的每个线程
* 实际运行时,每个线程仅执行一次,在测试方法运行结束后执行,类似于Loadrunner中的End方法
*/
public void teardownTest(JavaSamplerContext arg0) {
}
}
5.在idea里打成jar包封装,装进jmeter目录文件夹lib\ext内。
Project Structure --Artifacts --+ – JAR – From modules with dependencies OK–apply–OK后 Build–Build Artifacts 给老子biu~ biu~成功后,将会在项目根目录—out–artifacts中看到jar包 复制一份,装进jmeter目录文件夹lib\ext内。
6.重启Jmeter进行测试
打开bin\jmeter.bat构建线程组,在其下添加java请求和查看结果树,jar包导入成功的话,java请求里能够自动识别内部的类,且告知可以传入的参数及参数的默认值。(这里demo未使用传入参数,但是后续测试肯定会用到滴,例如利用jmeter里的随机函数作为传入参数来做文章) 点击绿色儿的小箭头,跑一跑试试看 成功~ 控制台
总结
到此,一个hprose for dot net 的服务端测试demo搭建完毕,实在是头痛,想了一周了裂了裂了。希望对大家有所帮助,最后,希望hprose for dot net用的人多多滴,人少真滴资料也少,找的我痛不欲生。
参考文档
极力推荐先做这个demo,给了我巨大的灵感,一半代码都是这个老哥写的呜呜呜我是废物hprose for java-githubhprose for dot net-github尝试了一下发现不行 可能我不太会使用,毕竟学的是.Net平台打jar包的正确步骤,可以参考给测试小姐姐讲RPC如何在ieda项目中引入jar包这个也可以参考