几种RPC模型的使用与比较

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

org.springframework.jms.remoting.JmsInvokerServiceExporter

org.springframework.jms.remoting.JmsInvokerProxyFactoryBean

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

RMI

Hessian/Burlap

HTTP Invoker

JAX-WS 

RMI

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

声明一个远程接口,接口必须继承java.rmi.Remote,方法需要抛java.rmi.RemoteException

为远程接口提供实现,实现类需要继承UnicastRemoteObject。

或者可以使用rmi相关命令创建skelton和stub。

启动一个RMI注册表并注册。

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

org.springframework.remoting.rmi.RmiServiceExporter

org.springframework.remoting.rmi.RmiProxyFactoryBean


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

package pac.testcase.ws; public interface MyService { public boolean inviteMeIn(); public String welcome(); } package pac.testcase.ws.impl; import pac.testcase.ws.MyService; public class MyServiceImpl implements MyService{ public boolean inviteMeIn() { return true; } public String welcome() { return "Everybody is welcome!!"; } }

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

下面是spring相关配置:

<bean id="myService" class="pac.testcase.ws.impl.MyServiceImpl" /> <bean class="org.springframework.remoting.rmi.RmiServiceExporter" p:service-ref="myService" p:serviceName="welcomeService" p:serviceInterface="pac.testcase.ws.MyService" />


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

/** * Set the host of the registry for the exported RMI service, * i.e. {@code rmi://HOST:port/name} * <p>Default is localhost. */ public void setRegistryHost(String registryHost) { this.registryHost = registryHost; } /** * Set the port of the registry for the exported RMI service, * i.e. {@code rmi://host:PORT/name} * <p>Default is {@code Registry.REGISTRY_PORT} (1099). * @see java.rmi.registry.Registry#REGISTRY_PORT */ public void setRegistryPort(int registryPort) { this.registryPort = registryPort; }


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

<bean id="clientSideService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" p:serviceUrl="rmi://localhost:1099/welcomeService" p:serviceInterface="pac.test.RemoteService" />


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

package pac.test; public interface RemoteService { public String welcome(); }


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

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); RemoteService service = (RemoteService)context.getBean("clientSideService"); System.out.println(service.welcome());

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

Hessian / Burlap 

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


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

几种RPC模型的使用与比较

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/2eaf27a13bb9bd1a56b67589e2f91611.html