设为首页 加入收藏

TOP

Spring - 几种RPC模型的使用与比较(一)
2015-02-02 14:22:37 来源: 作者: 【 】 浏览:39
Tags:Spring 几种 RPC 模型 使用 比较

Spring中,用JMS搞RPC时会用到:


spring在实现RPC的几种方式上都提供了风格一致的支持。
在这里我打算把几种RPC模型记录下来并作比较。


先从最基本的RMI开始。
RMI相关的API早在JDK1.1时就有了,我在这里简单描述一下RMI的原生实现(代码可以从别的地方参考)。


如果是spring实现RMI,方法会简单很多。
我们只需要用到两个类:



我简单定义一下接口和实现类:


?


简简单单,不需要继承其他任何东西,非常pojo。


下面是spring相关配置:



将我们的pojo导出为RMI服务,在这里我采用默认配置。
地址在默认情况时如下:



客户端方面使用RmiProxyFactoryBean,被代理的服务就像一个简单的bean一样:



配置中的pac.test.RemoteService就是那个简单的bean,根据客户端的需要,在这里重新定义一下。



这样就可以在服务端调用了,不用做什么Naming.lookup(serviceUrl)之类的操作,远程调用变得透明。


RMI虽然简单高效,但使用RMI会存在一些问题,比如java序列化的版本问题或者防火墙问题(RMI不是基于HTTP的)。


Hessian / Burlap?


Hessian和Burlap,现在进Caucho的网站都几乎见不到这方面的内容了。
我也不知道有没有人还会用这两个东东,虽然去年出了一个版本,但上一个版本是在2010年。
刚才在群里问了一下有没有人用,结果还真有人用Hessian,他们是C#和Java做通信。
Burlap性能更令人头疼,不知道还有没有人提及。
虽然不知道使用情况如何,但也在这里简单记录一下,拓展一下思维。



Hessian和Burlap都是由Caucho提供的,Hessian是Resin的一部分。
这两个东西就像同一件事物的两个部件,比如像这样的枪+链锯?



Hessian是binary transport protocol,但与RMI不同的是他不是java序列化对象,所以他可以和其他语言的程序通信,比如C++、C#、Python、Ruby什么的。
Burlap是基于XML的,自然也可以支持很多不同的语言。
当然,同样地传输内容下,XML的传输量会大一些。
如果要说有什么好处的话也只有可读性了。



实在懒得添加依赖再提供原生实现,但他并不复杂。

Creating a Hessian service using Java has four steps:



在这里我主要记录一下如何在spring中导出与调用Hessian service。
正如上面所说,我需要把服务配置到servlet engine中;
服务端和客户端都需要添加一个dependency:



正好我这边有个使用springMVC的应用,我就在这个基础上导出Hessian service。


简单写一个接口与实现:


?



我在spring-mvc.xml中曾经做了如下配置,并在*Controller中使用了RequestMapping注解去给URL做映射。
但这并不妨碍我导出Hessian service再为其映射一个URL:



导出Hessian service:



现在可以调用了,我需要在客户端声明一个接口(pac.test.HessianService),再用代理去调用:



调用:



console输出:


对于Burlap,几乎与Hessian的配置没什么区别;
只需要把HessianServiceExporter改为BurlapServiceExporter,
并将HessianProxyFactoryBean改为BurlapProxyFactoryBean即可。


RMI使用Java的序列化,而Hessian/Burlap则为了不同语言之间通信而使用私有的序列化。
如果我需要基于HTTP,但我并不需要多语言支持,我只想用Java...


?


?



我应该说这是基于Http的RMI吗?
虽然看起来两全其美,但也存在让人"遗憾"的地方,
(事实上不怎么遗憾的说,我曾经做过没有Spring的项目,连持久层框架都是自己实现,做得越久越痛苦...)
他没有所谓"原生"的实现,他是Spring的一部分,只能在Spring应用中使用。



Spring为这些RPC通信模型提供的相关类在命名上都有一致,都是:



自然地,HttpInvoker将用到



基于HttpInvoker的服务也像Hessian那样由DispatcherServlet进行分发。
鉴于很多相同的地方,我打算继续使用在上一篇中用Hessian通信的接口和实现类。


我几乎不用做任何工作,URL映射也不需要修改,我只需要将服务端的配置修改一下:



相应地,客户端也只需要修改一下class:



这样就保证了效率又解决了防火墙的问题,
后来我听有人说,他们用Hessian做跨语言通信时,基于Http这个特征并不能解决防火墙的问题。
不知道他们具体情况如何,似乎没说到一块儿...



看了Hessian之后突然感觉Web service这种东西好笨重啊(虽然也有一些方法可以克服部分问题)。
既然有Hessian,那为什么还要用Web service这种东西呢?
我突然开始怀疑起他存在的意义。
搜了一下,结果都是比较RPC通信模型的效率,没有人说他们为什么还要用(都应该有存在的意义吧)...
如果仅仅是效率的话都用Hessian不就得了?
带着这个问题我逛了逛stackoverflow,然后我得到了下面几种答案。



最后我还是没有得到让我满意的答案,倒是复习了Web service...
很多类似场景下人们都将Web service视为"standard"option。 既然如此...那就看看Web service吧。


?


?



看来使用web service是不可避免的。
我曾对这个有些抵触,因为他给我印象总是麻烦+慢(后来虽然方便了许多,但还是很慢)。
然后再去搜索"advantages of web service"什么的试着再让自己接受他。
简单记录一下如何用Spring导出Endpoint。


假设我想在有一个Spring应用,我需要把一个Pojo或者一部分方法导出为Web Service。
但这会有一个问题——Endpoint的生命周期是由JAX-WS runtime来管理(The lifecycle of such an endpoint instance will be managed by the JAX-WS runtime),
Spring context中的Bean无法autowire到Endpoint中,而我要导出的那些东东都用到了Spring管理的Bean。



对此,我们有两个解决方法:



我上面括号中的那段话是引用的SpringBeanAutowiringSupport的javaDoc。
使用该类的典型案例就是bean注入到JAX-WS endpoint类中(人家注释上写的),任何一个生命周期不是由Spring来管理的场景都可以用到他。
而我们只需要继承这个类,也就是说创建一个实例时会调用父类的无参构造方法,我们来看看他的构造方法:



那就试试看:


?


接着发布一下:



调用:



写一个EndPoint还要继承和业务无关的类,让人不爽...而且发布和调用都麻烦。
那试试SimpleJaxWsServiceExporter,只需要简单的配置就可以导出一个EndPoint。
但是他也有需要注意的地方,引用一下该类的javaDoc:



SimpleJaxWsServiceExporte

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Python面向对象编程学习笔记 下一篇Effective Java - 避免使用finali..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: