Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。这也正是工作时引入Hessian的一个重要原因,简单易配置。但是同样也有缺点,高版本对于低版本的向下兼容处理的并不好、一直流传一句话,“对于hessian,能不用高版本就不用高版本”,这句话充分说明了大家对于Hessian一些错误的困扰,那么下面总结一下最近遇到的Hessian相关的问题。
1、Nginx 使用反向代理时 Hessian 的 411 错误
报错如下:
com.caucho.hessian.client.HessianConnectionException: 411:java.io.IOException: Server returned HTTP response code: 411 for URL:http://xxxx/xxx/xxxService
排查过程:
刚一开始发现报错时,以为是server端返回的报错,还跑去问server端是不是报错了。。。后来了解到server端添加了nginx代理,不再支持绑定ip直连接口的方式。通过查资料发现Hessian在Nginx反向代理的情况下存在问题。
问题原因:
首先来看下 HTTP 411 错误的解释: Length Required 服务器不能处理请求,除非客户发送一个Content-Length 头。( HTTP 1.1 新)这是因为 Hessian 与服务端通信默认是采取分块的方式 (chunked encoding) 发送数据,而反向代理要获得 Content-Length 这个头,才能处理请求,但是 Hessian 的请求中并没有加入这个参数。
解决办法:
根据以上问题出现的原因,最直接想到的办法就是,缺少一个Content-Length那么我可以传递这个参数给server端,从而避免这个报错。具体办法是需要将将要发送的数据缓存下来。计算出content-length随着请求发送给server端,以满足Nginx需要这个参数的需求。
然而这样计算比较麻烦,所以可以使用Hessian提供的一个参数进行设置,setChunkedPost(false),(可以在初始化HessianFactory对象时写在构造函数里)这个是用来设置 Hessian 是否以分块发送的方式与服务端交换数据的参数,默认为true,设置为false时,向server端发送数据时就不采用分块方式,从而避免了报错。
2、Hessian调用重载方法报错问题(expected end of call)
报错如下:
org.springframework.web.util.NestedServletException: Hessian skeleton invocation failed; nested exception is
com.caucho.hessian.io.HessianProtocolException:
.......
Caused by: com.caucho.hessian.io.HessianProtocolException: getList: expected end of call ('xxx') at 0x53 (S).
.....
com.caucho.hessian.client.HessianRuntimeException: com.caucho.hessian.io.HessianProtocolException:
.......
排查过程:
Caused by: com.caucho.hessian.io.HessianProtocolException: getList: expected end of call ('xxx') at 0x53 (S).
根据以下报错可以看出是调用getList方法时报错,将server端提供的接口反编译发现,getList存在多个,也就是存在重载的情况。
问题原因:
查找相关资料发现,Hessian的HessianFactory的isOverloadEnabled属性默认为false。这个参数如果为false,Hessian调用的时候获取接口仅根据方法名;反之,Hessian调用时决定调用哪个方法是通过方法名和参数类型一起决定。所以也就解释了,存在重载的方法时为什么会报以上错误。
解决办法:
在初始化HessianFactory对象时写在构造函数里,对factory设置 setOverloadEnabled(true) ,问题解决。
3、Hessian由于版本不兼容导致的报错(com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d )
报错如下:(借用了一下别人的报错信息,自己的忘记保存了。。。)
2011-4-25 16:14:44 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet remoting threw exception
com.caucho.hessian.io.HessianProtocolException: expected string at 0x6d
at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2882)
at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2830)
at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1362)
at com.caucho.hessian.io.Hessian2Input.readMethod(Hessian2Input.java:272)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:249)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:221)
at org.springframework.remoting.caucho.Hessian2SkeletonInvoker.invoke(Hessian2SkeletonInvoker.java:67)
at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:147)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:819)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:754)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:399)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
排查过程:
这个报错真心花了好几个小时才搞定。。。从报错信息上来看,仅仅报出了expected string at 0x6d,这个信息没什么参考价值。。。但是我看了下面com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2882),为什么会出现Hessian2?带着疑问我去查了一下,发现高版本和低版本Hessian的协议已经变化了,低版本的是Hessian1,而高版本的是Hessian2。但是我管理的系统中Hessian版本和server端的版本一直没有变化呀,为什么会这样报错?突然想起来我resin的版本升级了,从3.0.28升级到了3.1,经过查询resin3.1新引入了Hessian的包,而且jar包的版本是高于我当前系统的低版本的,并且resin启动时会强制加载它的hessian包。。。orz。。。所以基本上定位了,就是版本不兼容。然而我还没发让server端更改高版本,所以只能自己想办法搞定这个事情。
问题原因:
Resin3.1引入的Hessian版本是高版本,其中使用的协议为Hessian2,而server端是低版本使用Hessian1协议,协议不匹配,通信后的结果自然是你不懂我我不懂你。
解决办法:
很多文章写解决办法都是换版本,但是在实际情况下,作为接口的使用者,没有能力更没有理由让server端按照你的意思去升级版本,但是这事就无解了吗?并不是,可以设置两个参数来解决这个事情。
factory.setHessian2Reply(false);
factory.setHessian2Request(false);
void setHessian2Reply(boolean isHessian2)
True if the proxy can read Hessian 2 responses.
void setHessian2Request(boolean isHessian2)
True if the proxy should send Hessian 2 requests.
根据Hessian的文档说明发现,这两个参数一个是设置用Hessian2协议发请求,一个是设置用Hessian2协议收回复,在高版本中这个参数默认是true,所以我们可以把它们设置成false,也就是通知系统强制用Hessian1协议来收发信息,问题也随之解决。(实验一段时间并未发现问题,目前看这个方案可行)
总结:
以上就是这阶段系统中Hessian出现的各种问题的一个小总结,可能有些东西叙述起来略显啰嗦,也有可能某些东西存在问题,希望大家批评指正。
对于开源的软件来说,版本冲突的问题一直都是困扰程序猿的大问题,然而作为使用者的我们如何避免入坑呢?或许官方文档才是最值得依靠和研读的,即使它是英文的。
分享到:
相关推荐
在Spring+iabtis框架中,增加hessian接口,要实现以下几点: 1.绕过系统本身的认证,拦截器直接将该实现方法的...如果解决方案有不足之处,欢迎留言中进行斧正。如果不懂也可以留言咨询,本人最近会尽量回来看看。
标题中的“闲着没事Hessian开发WebService的总结(一)”表明这是一篇关于使用Hessian框架开发Web服务的文章,作者可能在其中分享了个人的经验和理解。Hessian是一种轻量级的远程调用协议,它允许Java和.NET之间进行...
总结,Hessian协议提供了一种高效、跨语言的RPC解决方案,尤其适合Java和Python之间的通信。通过使用Hessian,开发者可以轻松地构建分布式系统,实现服务之间的便捷调用。案例中的文件提供了不同角度的分析和实践...
Hessian 协议格式 Hessian 协议是一种轻量级的 remoting on http 工具,使用简单的方法提供了 RMI 的功能。采用的是二进制 RPC 协议,所以它很适合于发送二进制数据。Hessian 主要用作面向对象的消息通信。 ...
**Hessian:深入理解与应用** Hessian是一种二进制Web服务协议,它由Caucho Technology公司开发,主要用于提供轻量级、高效的远程方法调用(Remote Method Invocation,RMI)服务。Hessian的目标是简化分布式系统...
Hessian3.2.1是Hessian的后续版本,通常会包含一些bug修复和性能提升。这个版本可能引入了对新特性的支持,例如改进了类型处理,增加了对更多数据类型的兼容性,或者优化了RPC调用的效率。此外,可能会有对其他开源...
总结起来,Hessian是一种高效的二进制Web服务协议,它简化了分布式系统中对象的传输,并提供了跨语言的支持。理解和使用Hessian可以帮助我们构建更快速、更灵活的远程服务调用系统。通过深入研究源码和利用相关工具...
- 在实际开发中,我们可能会需要编写一些辅助工具类来处理Hessian的相关操作,例如Hessian2Input和Hessian2Output,它们用于读写Hessian序列化的二进制流。 6. **安全性与优化**: - 虽然Hessian协议效率高,但其...
Hessian由Caucho Technology开发,旨在提供轻量级、高性能的远程调用解决方案。在这个案例中,我们关注的是Hessian的版本4.0.37,即"hessian4.0.37.jar"。 Hessian4.0.37是Hessian协议的一个稳定版本,提供了对Java...
为了方便调试和测试,可以使用一些工具,如Hessian Proxy Factory(一个命令行工具)或者Hessian Browser(一个网页工具),它们可以帮助我们查看和测试Hessian服务。 **常见问题与解决方案** 在实际应用中,可能会...
总结起来,Hessian矩阵在心血管分割中的应用是一种有效的图像分析技术,它可以准确检测和追踪图像中的血管结构。通过理解和应用Hessian矩阵,可以开发出高效、精确的自动分割算法,这对医学图像分析领域具有重大意义...
这个协议设计的目标是提供轻量级、高效的RPC(Remote Procedure Call)解决方案,尤其适用于内部网络或需要低延迟通信的场景。在这个“hessian服务端 客户端 可运行”的压缩包文件中,很可能包含了一个完整的示例,...
总结来说,多尺度Hessian滤波器图像增强技术是一种强大的工具,尤其适用于医学影像分析、遥感图像处理等领域,它能有效检测和增强图像中的线性结构,提高特征的可识别性。通过MATLAB提供的相关函数,我们可以方便地...
总的来说,Hessian提供了高效、轻量级的跨语言通信解决方案,尤其适合对性能有较高要求的场景。通过学习和实践这个Hessian demo,你将能够更好地应对涉及远程调用和数据交换的问题。无论是Java开发者还是C++开发者,...
3. **Hessian服务器**:`hessianServer.sln`是Visual Studio的解决方案文件,包含了服务端的全部代码和配置。服务器端的主要任务是暴露可被远程调用的服务接口,这些接口通常以方法的形式存在,可以接收客户端的请求...
总之,Hessian作为一种高效的远程调用解决方案,简化了客户端和服务端之间的通信,使得跨网络调用变得简单而高效。在实际开发中,合理地使用Hessian可以提高系统的可扩展性和可维护性。然而,随着微服务架构的普及,...
总结来说,HessianServer是利用Hessian协议构建的高效服务端程序,它简化了分布式系统中的通信流程,提供了良好的性能和便捷的使用体验。然而,实现一个健壮的Hessian服务端还需要关注安全性、版本兼容性、性能优化...
Hessian协议是http://caucho.com/公司开发的一种实用的web服务技术,它采用二进制数据,传输效率比较高,简单易用,是C#.NET/IIS环境快速开发web服务应用的一种解决方案。本资源中包含Hessian协议的C#版源代码,由于...
《Hessian应用详解》 Hessian,一种轻量级的二进制协议,因其高效、简单的特点,在分布式服务中被广泛应用。它允许开发者在HTTP上透明地调用远程方法,就像是本地方法调用一样,极大地提高了开发效率和系统性能。...
通过研究这些文件,开发者可以直接看到问题的现象,理解问题的上下文,并尝试各种解决方案,如更新Hessian到兼容的版本、调整Spring配置、修复序列化类或者优化异常处理逻辑。 总的来说,Hessian 4.0.7与Spring ...