性能工具之Jmeter压测Hprose RPC服务
概述
Hprose(High Performance Remote Object Service Engine),国人开发的一个远程方法调用的开源框架。它是一个先进的轻量级的跨语言跨平台面向对象的高性能远程动态通讯中间件,它支持众多语言,例如nodeJs, C++,.NET,Java,Delphi,Objective-C,ActionScript,JavaScript,ASP,PHP,Python, Ruby,Perl等。
什么是RPC?
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。 其实简单的说,就是象调用本地的类的方法样来调用服务器端的方法实现。
具体参考以下文章:
Hprose特点
支持几乎所有常见语言的实现,包括浏览器中的javascript
成熟稳定,已经在很多项目中得到验证
一直在持续稳步更新
国人开发,有QQ群在线支持,回复比较快速(5分钟之内)
和实体能保持很好的兼容性,实体工作量较小
Hprose服务端
Hprose 2.0 for Java 支持多种底层网络协议绑定的服务器,比如:HTTP 服务器,TCP 服务器和 WebSocket 服务器。 HTTP 服务器支持在 HTTP、HTTPS 协议上通讯。 TCP 服务器支持在 TCP 协议上通讯,并且支持全双工和半双工两种模式。 WebSocket 服务器支持在 ws、wss 协议上通讯。
Hprose客户端
Hprose 2.0 for Java 支持两种底层网络协议绑定的客户端:HTTP 客户端 和 TCP 客户端。 其中 HTTP 客户端支持跟 HTTP、HTTPS 绑定的 Hprose 服务器通讯。 TCP 客户端支持跟 TCP 绑定的 Hprose 服务器通讯,并且支持全双工和半双工两种模式。 尽管支持这两种不同的底层网络协议,但除了在对涉及到底层网络协议的参数设置上有所不同以外,其它的用法都完全相同。
官网地址: //hprose.com/
实现逻辑
Hprose应用大致就做三件事:
复制Hprose文件进项目
写Hprose服务端
写Hprose客户端
Hprose服务端要做的事就两件:
new一个HproseHttpServer对象
用这个对象发布服务,包括函数、方法、对象甚至类
Hprose客户端要做的事就两件:
new一个HproseHttpClient对象
用这个对象调用服务端发布的各种服务
压测示例
此处我们使用官方自带的HellWorld示例
源代码://github.com/hprose/hprose-java
写Hprose服务端
首先创建一个maven web项目,并引入hprose Stub JAR包
-
<dependencies>
-
<!--引入hprose Stub-->
-
<dependency>
-
<groupId>org.hprose</groupId>
-
<artifactId>hprose-java</artifactId>
-
<version>2.0.38</version>
-
</dependency>
-
</dependencies>
在WebRoot/WEB-INFO/Lib目录下引入servlet和websocket的JAR包
创建hello服务类,可以写两个很简单的sayHello方法和add方法
-
/***
-
* 服务类
-
*/
-
-
public class Hello {
-
-
/***
-
* 返回hello+客户端传参
-
* @param name
-
* @return
-
*/
-
public String sayHello(String name) {
-
return "Hello " + name + "!";
-
}
-
-
/**
-
* 返回两个数字的和
-
* @param a
-
* @param b
-
* @return
-
*/
-
public String add(int a,int b)
-
{
-
int c=a+b;
-
return "结果是:"+c;
-
}
-
}
编写一个服务发布类WebSocketServer绑定WebSocketServer
-
/***
-
* 服务发布类
-
* WebSocket 绑定
-
* Hprose RPC也可以工作于WebSocket之上,数据以二进制数据的方式在WebSocket上发送和接收。
-
* Hprose RPC添加了4个字节的头作为请求唯一标识(id),服务器端不需要关心请求唯一标识(id)如何编码,只需要在应答中重复它就可以了。
-
*/
-
-
@ServerEndpoint("/wshello")
-
public class WebSocketServer {
-
private HproseWebSocketService service = new HproseWebSocketService();
-
public WebSocketServer() {
-
//new出服务对象,发布类里面所有的公共方法
-
service.add(new Hello());
-
}
-
@OnOpen
-
public void onOpen(Session session, EndpointConfig config) {
-
service.setConfig(config);
-
}
-
@OnMessage
-
public void onMessage(ByteBuffer buf, Session session) throws IOException {
-
service.handle(buf, session);
-
}
-
@OnError
-
public void onError(Session session, Throwable error) {
-
service.handleError(session, error);
-
}
-
}
主要工作都完成了,接着需要在web.xml里注册一下
-
<?xml version="1.0" encoding="UTF-8"?>
-
<web-app version="2.5" xmlns="//java.sun.com/xml/ns/javaee" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//java.sun.com/xml/ns/javaee //java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
-
<servlet>
-
<!--注册服务-->
-
<servlet-name>HelloServlet</servlet-name>
-
<servlet-class>hprose.server.HproseServlet</servlet-class>
-
<init-param>
-
<param-name>class</param-name>
-
<param-value>hprose.hello.server.Hello</param-value>
-
</init-param>
-
<init-param>
-
<param-name>crossDomain</param-name>
-
<param-value>true</param-value>
-
</init-param>
-
</servlet>
-
<!--绑定URL-->
-
<servlet-mapping>
-
<servlet-name>HelloServlet</servlet-name>
-
<url-pattern>/Hello</url-pattern>
-
</servlet-mapping>
-
<session-config>
-
<session-timeout>
-
30
-
</session-timeout>
-
</session-config>
-
<welcome-file-list>
-
<welcome-file>index.html</welcome-file>
-
</welcome-file-list>
-
</web-app>
完成后运行tomcat,浏览器自动打开//localhost:8888/Hello,我们可以看到这个服务已经成功发布了。
写Hprose客户端
接下我们写HelloClient类测试下服务是否ok
-
/**
-
* Hprose客户端
-
*/
-
public class HelloClient {
-
public static void main(String[] args) throws IOException {
-
//new一个HproseHttpClient对象
-
HproseHttpClient client = new HproseHttpClient();
-
//使用无参构造器创建的客户端,在进行调用前,需要先调用useService方法初始化服务器地址
-
client.useService("//localhost:8080/Hello");
-
//使用invoke方法来动态调用服务。
-
String result = (String) client.invoke("sayHello", new Object[] { "Hprose" });
-
System.out.println(result);
-
result = (String) client.invoke("sayHello", new Object[] { "7DGroup" });
-
System.out.println(result);
-
System.out.println(client.invoke("add",new Object[]{1,6}));
-
}
-
}
测试成功后,我们把hprose jar包拷贝到apache-jmeter-4.0\lib\ext下
Jmeter压测
打开Jmeter,设置线程组为5个
新建一个BeanShell Sampler及察看结果树,拷贝HelloClient代码到BeanShell script内,使用随机数函数对请求的数字进行参数化
运行并查看Jmeter控制台输出结果
至此,我们的一个压测Hprose RPC服务的小例子就完成了。