我有spring应用程序A, B和C在单个Tomcat 7实例上运行。
A是唯一的入口点,依赖于B &C的功能。B和C通过rmi公开它们的服务bean。将来会有更多像B和C (D, E…)这样的应用。
目前rmi注册表是由A在加载时通过
的上下文加载器启动的 <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="${batch.rmi.port}"/>
</bean>
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl" value="service:jmx:rmi://localhost:${batch.rmi.port}"/>
</bean>
我的问题是,当A重新启动rmi注册表也重新启动和B &C丢失了它们在注册表中的条目。此外,在服务器重启时,我不能保证A会在B之前加载;C:到目前为止……由于命名顺序?).
我找不到在server.xml中设置侦听器以便在服务器启动时加载注册表的提及。所有的谷歌对我来说是JmxRemoteLifecycleListener启动jmx -我不想要运行(远程配置是不鼓励在我的情况下)。
编辑# 1
显然我可以这样做通过MBean加载org.apache.catalina.mbeans.ServerLifecycleListener…升到6,从7降下来了。
编辑# 2
初始临时解决方案是在重启后手动重启失败的应用程序。当前的临时解决方案是专用的应用程序(仅限rmi上下文),路径为"a…"(我猜一些符号/数字会更合适),以便Tomcat首先加载它。不漂亮,但目前可以工作-直到有更多的"a…"应用程序或tomcat行为在下一次更新中改变。
编辑# 3
B,C被暴露为
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="host" value="${batch.rmi.host}"/>
<property name="port" value="${batch.rmi.port}"/>
</bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="ExampleBatchJob"/>
<property name="service" ref="jobLauncherController"/>
<property name="serviceInterface" value="org.example.IJobLauncherController"/>
<property name="registry" ref="registry"/>
</bean>
当指定host参数时,应用程序查找注册表,如果找不到,从不尝试创建。另一种解决问题的方法是rmicregistryfactorybean没有设置"查找注册表,如果找不到就初始化一个" ->我的误解,由aecolley解释。
通过将RMIRegistry与depends-on
挂钩到A(而不是其他),您可以确保在A被销毁后不久将销毁RMIRegistry。(参见Spring文档)
RmiRegistryFactoryBean确实有一个设置,可以在没有找到注册表时创建注册表:只需省略host
属性。但是,如果可能的话,我建议使所有使用注册表的应用程序依赖于与depends-on
相同的注册表,以消除关于哪一个首先开始的任何随机性。