远程通信框架--hessian应用分享

本文介绍 Hessian 远程服务的原理及其实现细节,包括基于 Binary-RPC 的通讯机制、序列化过程、与多种协议的效率对比,以及客户端和服务端的基本交互流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://kfliyangfan.iteye.com/category/121452

一、什么是Hessian

      Hessian 是一个基于 binary-RPC 实现的远程通讯 library。使用二进制传输数据。Hessian通常通过Web应用来提供服务,通过接口暴露。Servlet和Spring的DispatcherServlet都可以把请求转发给Hessian服务。由以下两种方式提供,分别为:com.caucho.hessian.server.HessianServlet、org.springframework.web.servlet.DispatcherServlet。


关于hessian的7个问题:


1、是基于什么协议实现的?

基于Binary-RPC协议实现。


2、怎么发起请求?

需通过Hessian本身提供的API来发起请求。


3、怎么 将请求转化为符合协议的格式的?

Hessian通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。


4、使用什么 传输协议传输?

Hessian基于Http协议进行传输。


5、响应端基于什么机制来接收请求?

响应端根据Hessian提供的API来接收请求。


6、怎么将流还原为传输格式的?

Hessian根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了。


7、处理完毕后怎么回应?

处理完毕后直接返回,hessian将结果对象进行序列化,传输至调用端。

 

二、hessian的优缺点

 

       优点:

 

简单易用,面向接口,通过接口暴露服务,jar包只有200300k,不需要配置防火墙

效率高,复杂对象序列化速度仅次于RMI,简单对象序列化优于RMI,二进制传输

    多语言支持:wikiJavaFlash/FlexPythonC++.NET C#PHPRubyObjective-C

可与spring集成,配置简单,HessianServiceExporte

 

缺点:

 

缺乏安全机制,传输没有加密处理

异常机制不完善,总是报一些错误,错误原因也是千奇百怪,提示信息不足

事务处理欠缺

版本问题,spring 2.5.6对照3.1.3版,spring 3对照4.0及以上版本,需要使用spring MVC部分内容

 


 

三、各个通讯协议对比:
通讯效率测试结果:
RMI > Httpinvoker >= Hessian >> Burlap >> Web service
1.RMI 是 Java 首选远程调用协议,非常高效稳定,特别是在数据结构复杂,数据量大的情况下,与其他通讯协议的差距尤为明显。但不能跨语言。
2.HttpInvoker 使用 java 的序列化技术传输对象,与 RMI 在本质上是一致的。从效率上看,两者也相差无几, HttpInvoker 与 RMI 的传输时间基本持平。
3.Hessian 在传输少量对象时,比 RMI 还要快速高效,但传输数据结构复杂的对象或大量数据对象时,较 RMI 要慢 20% 左右。但这只是在数据量特别大,
数据结构很复杂的情况下才能体现出来,中等或少量数据时, Hessian并不比RMI慢。 Hessian 的好处是精简高效,可以跨语言使用,而且协议规范公开,
我们可以针对任意语言开发对其协议的实现。另外, Hessian与WEB服务器结合非常好,借助WEB服务器的成熟功能,在处理大量用户并发访问时会有很大优势,在资源分配,
线程排队,异常处理等方面都可以由成熟的WEB服务器保证。而 RMI 本身并不提供多线程的服务器。而且,RMI 需要开防火墙端口, Hessian 不用。
4.Burlap 采用 xml 格式传输。仅在传输 1 条数据时速度尚可,通常情况下,它的毫时是 RMI 的 3 倍。
5.Web Service 的效率低下是众所周知的,平均来看, Web Service 的通讯毫时是 RMI 的 10 倍。

四、基本流程

客户端必须具备以下几点:
   ·java客户端包含Hessian.jar的包。
   ·具有和服务器端结构一样的接口。
·利用HessianProxyFactory调用远程接口。
·使用spring方式需要配置HessianProxyFactoryBean

JAVA服务器端必须具备以下几点:
  ·包含Hessian的jar包。
  ·设计一个接口,用来给客户端调用。
  ·实现该接口的功能。
  ·配置web.xml,配好相应的servlet。
  ·对象必须实现Serializable 接口。
  ·对于spring方式DispatcherServlet拦截url,HessianServiceExporter提供Bean服务

五、源码分析
1.     客户端发起请求
使用动态代理来实现的。除去 spring 对其的封装,客户端主要是通过 HessianProxyFactory 的 create 方法就是创建接口的代理类,该类实现了接口, 
JDK 的 proxy 类会自动用 InvocationHandler 的实现类(该类在 Hessian 中表现为 HessianProxy )的 invoke 方法体来填充所生成代理类的方法体。

客户端调用 hessian 服务时:

HessianProxy 类的:
Java代码    收藏代码
  1. invoke(Object proxy, Method method, Object []args){  
  2.                   String methodName = method.getName();// 取得方法名  
  3.                   Object value = args[0]; // 取得传入参数  
  4.                   conn = sendRequest(mangleName, args) ;      // 通过该方法和服务器端取得连接  
  5.                   httpConn = (HttpURLConnection) conn;  
  6.                   code = httpConn.getResponseCode();    // 发出请求  
  7.   
  8.                                     // 等待服务器端返回相应…………  
  9.   
  10.                   InputStream is = conn.getInputStream();  
  11.                   AbstractHessianInput in = _factory.getHessianInput(is); //转化为hessian自己的输入输出API  
  12.                   Object value = in.readObject(method.getReturnType()); // 取得返回值  
  13. }  
 

Java代码    收藏代码
  1. URLConnection sendRequest(String methodName, Object []args){  
  2.                   URLConnection  conn = _factory.openConnection(_url);      // 创建 URLConnection   
  3.                   OutputStream os = conn.getOutputStream();  
  4.                   AbstractHessianOutput out = _factory.getHessianOutput(os); // 封装为 hessian 自己的输入输出 API  
  5.                   out.call(methodName, args);  
  6.                   return conn;  
  7. }  
 
2.     服务器端接收请求并处理请求

服务器端截获相应请求交给: (Hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);
 org.springframework.remoting.caucho.HessianServiceExporter

具体处理步骤如下:
a)HessianServiceExporter 类
Java代码    收藏代码
  1. (HessianExporter) invoke(request.getInputStream(), response.getOutputStream());  
 
        b)HessianExporter 类
Java代码    收藏代码
  1. (Hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);  
 
c)Hessian2SkeletonInvoker 类
Java代码    收藏代码
  1. //将输入输出封转化为转化为 Hessian 特有的 Hessian2Input 和 Hessian2Output         
  2.               Hessian2Input in = new Hessian2Input(isToUse);          
  3.               in.setSerializerFactory(this.serializerFactory);  
  4.       
  5.               AbstractHessianOutput out = null;       
  6.               int major = in.read();          
  7.               out = new Hessian2Output(osToUse);          
  8.               out.setSerializerFactory(this.serializerFactory);       
  9.               (HessianSkeleton) this.skeleton.invoke(in, out);  
 
d)HessianSkeleton 类
Java代码    收藏代码
  1. //读取方法名  
  2.                     String methodName = in.readMethod();          
  3.                 Method method = getMethod(methodName);  
  4.                   
  5.                     //读取方法参数  
  6.                     Class []args = method.getParameterTypes();  
  7.                     Object []values = new Object[args.length];  
  8.           
  9.                     //执行相应方法并取得结果  
  10.                     result = method.invoke(service, values);  
  11.                       
  12.                     //结果写入到输出流  
  13.                     out.writeObject(result);  
 
                   先简单看下hessian的整体流程,下一篇中详细分析一个小DEMO来看hessian的具体应用。不过应用hessian时有几个问题需要注意:
    1.实体类必须实现序列化接口

                    2.远程对象有重载方法时,setOverloadEnabled(true),否则回报异常

                    3.和spring集成时注意版本冲突问题

                    4.配置文件名称与路径问题,默认${servlet-name}-servlet,想要更改时需配置namespace

                    5.没有超时处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值