Skip to content

spring 中rmi服务的客户端负载与rmi服务的动态注册与发现。希望对使用了rmi的老系统又不想改用其他PRC框架的并且又想拥有这些特性的有所帮助

Notifications You must be signed in to change notification settings

winsnlife/cluster4spring

Repository files navigation

这是cluster4spring 框架的扩展。目前版本:1.0.2 源项目地址:http://www.theserverside.com/discussions/thread/45766.html

本人在他的基础上,修复了一些bug。

主要修复了客户端使用多个URL调用多个rmi服务的时候,如果服务端重启,那么这个服务将不会再被调用的问题。

另外,个人基于zookeeper实现了服务的注册与发现(依赖com.101tec:zkclient:0.8,zookeeper:3.4.6+,spring234版本都是可以的,其他基础包自行添加了)。

注: 该项目已在生产环境下运行一年半有余. 个人编译好了cluster4spring-1.0.2.jar,可直接下载使用 有问题欢迎提出、指正。

下面是案例:

一、客户端负载,静态配置

(1)、客户端

<bean id="rmiClientSetting" abstract="true">
	<!-- 是否启动时加载stub -->
	<property name="refreshEndpointsOnStartup" value="false" />
	<!-- 调用异常时,将重新加载stub -->
	<property name="refreshEndpointsOnConnectFailure" value="true" />
	<!-- 调用失败时是否切换到其他服务端 -->
	<property name="switchEndpointOnFailure" value="true" />
	<!-- 追踪拦截器启用 -->
	<property name="registerTraceInterceptor" value="true" />
	<!-- 缓存stub 继承AbstractRmiShortFormProxyFactoryBean才有-->
	<property name="cacheEndpoints" value="true" />
	
</bean>

<bean id="serviceName"
	  class="org.softamis.cluster4spring.rmi.RmiUrlListProxyFactoryBean" parent="rmiClientSetting">
	<!-- 远程服务对象接口类 -->
	<property name="serviceInterface" value="com.xxxx.xxxx.xxx"/>
	<!-- 远程对象地址list ,如果第一个无法使用,会抛异常,然后使用第二个去调用远程对象方法返回结果-->
	<property name="serviceURLs">
		<list>
			<value>rmi://ip1:60000/serviceName</value>
			<value>rmi://ip2:60000/serviceName</value>
		</list>
	</property>
	<!-- 调用时选择那个url的策略 -->
	<property name="endpointSelectionPolicy">
		<bean class="org.softamis.cluster4spring.support.invocation.ShuffleEndpointSelectionPolicy"/>
	</property>
</bean>

(2)、服务端
	<!-- RMI调用拦截器 控制调用权限 -->
	<bean id="rmiSecurityInterceptor" class="org.softamis.cluster4spring.support.RmiSecurityInterceptor">
		<!-- 这里配置允许访问rmi的客户端IP地址 ,空时允许所有IP访问-->
		<property name="allowed">
			<set>
				<!--
				<value>ip</value>
				-->
			</set>
		</property>
	</bean>
	
	<bean id="rmiServerPropertySetting" abstract="true">
		<property name="interceptors">
			<list>
				<ref bean="rmiSecurityInterceptor"/>
			</list>
		</property>
		<property name="registryPort" value="60000"/><!-- 默认1099 -->
		<property name="servicePort" value="60000"/><!--tcp通信端口,不指定就随机 -->
	</bean>
	
	<bean id="obj" class="xxx.xxx.x"/>
	
	<bean class="org.springframework.remoting.rmi.RmiServiceExporter" parent="rmiServerPropertySetting">
		<property name="serviceName" value="serviceName"/>
		<property name="service" ref="obj" />
		<property name="serviceInterface"  value="com.xxxx.xxxx.xxx" />
	</bean>

二,使用zookeeper动态注册与发现rmi服务

注:rmi服务注册到zookeeper上路径:/rmiRegistryRoot/provider/rmi服务名
	所以务必定义rmi服务名时保证唯一(主要是为了客户端与服务端的接口存放包名可以不相同这个特性)

(1)、客户端

<bean id="rmiClientSetting" abstract="true">
	<!-- 是否启动时加载stub -->
	<property name="refreshEndpointsOnStartup" value="false" />
	<!-- 调用异常时,将重新加载stub -->
	<property name="refreshEndpointsOnConnectFailure" value="true" />
	<!-- 调用失败时是否切换到其他服务端 -->
	<property name="switchEndpointOnFailure" value="true" />
	<!-- 追踪拦截器启用 -->
	<property name="registerTraceInterceptor" value="true" />
	<!-- 缓存stub 继承AbstractRmiShortFormProxyFactoryBean才有-->
	<property name="cacheEndpoints" value="true" />
</bean>

<!--云呼WebSocket服务-->
<bean id="zkClient" class="org.softamis.cluster4spring.rmi.ZookeeperFactoryBean">
	<!--zookeeper 主机-->
	<property name="zkHosts" value="x.x.x.x:2181,x.x.x.x2:2181,x.x.x.x3:2181"/>
	<property name="zkSessionTimeOut" value="15000"/>
	<property name="zkConnectionTimeout" value="5000"/>
</bean>

<bean id="rmiClientSetting4Zoo" abstract="true" parent="rmiClientSetting">
	<property name="zkClient" ref="zkClient"/>
</bean>

<!--最新版已默认随机策略,可以不配置调用策略-->
<bean id="webSocketService" class="org.softamis.cluster4spring.rmi.ZookeeperRmiDiscoveringProxyFactoryBean" parent="rmiClientSetting4Zoo">
	<!--rmi服务名是必须,用来检索rmi服务列表-->
	<property name="serviceName" value="rmiWebSocketService"/>
	<property name="serviceInterface" value="xxxx.xxx.xx.WebSocketService"/>
</bean>

(2)、服务端
<!-- RMI调用拦截器 控制调用权限 -->
	<bean id="rmiSecurityInterceptor" class="org.softamis.cluster4spring.support.RmiSecurityInterceptor">
		<!-- 这里配置允许访问rmi的客户端IP地址 ,空时允许所有IP访问-->
		<property name="allowed">
			<set>
				<!--
				<value>ip</value>
				-->
			</set>
		</property>
	</bean>
	
	<bean id="rmiServerPropertySetting" abstract="true">
		<property name="interceptors">
			<list>
				<ref bean="rmiSecurityInterceptor"/>
			</list>
		</property>
		<property name="registryPort" value="60000"/><!-- 默认1099 -->
		<property name="servicePort" value="60000"/><!--tcp通信端口,不指定就随机 -->
	</bean>
	
	<bean id="obj" class="xxx.xxx.x"/>
	
	<bean id="xxxExporter" class="org.springframework.remoting.rmi.RmiServiceExporter" parent="rmiServerPropertySetting">
		<!--rmi服务名是必须,用来检索rmi服务列表-->
		<property name="serviceName" value="rmiWebSocketService"/>
		<property name="service" ref="obj" />
		<property name="serviceInterface"  value="com.xxxx.xxxx.WebSocketService" />
	</bean>
	
	<!--注册到zookeeper-->
	<bean class="org.softamis.cluster4spring.rmi.ZookeeperSpringRmiPublisher">
		<!--zookeeper 主机-->
		<property name="zkHosts" value="x.x.x.x:2181,x.x.x.x2:2181,x.x.x.x3:2181"/>
		<property name="zkSessionTimeOut" value="15000"/>
		<property name="zkConnectionTimeout" value="5000"/>
		<property name="rmiServiceExporters">
			<set>
				<ref bean="xxxExporter"/>
			</set>
		</property>
	</bean>

About

spring 中rmi服务的客户端负载与rmi服务的动态注册与发现。希望对使用了rmi的老系统又不想改用其他PRC框架的并且又想拥有这些特性的有所帮助

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published