我遇到的情况是,使用 Spring 配置的 RMI 服务RmiServiceExporter
启动得很好,并且可以使用一段时间 - 然后在一段时间后,即使该 Spring 上下文的 Java 进程仍在运行,该服务也不可用.
目前的解决方法是重新启动 java 进程,但这在生产环境中是难以接受的。我无法弄清楚,甚至开始猜测,为什么会发生这种情况,或者寻找什么可能会出错。没有任何 S/O 或 Google 搜索有用,因为我发现的只是根本RmiServiceExporter
无法启动、启动不正常然后后来又失败的示例。任何线索都会很有用。
lsof | head -1;lsof | grep 1197
,服务失败前的输出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 6882 ubuntu 176u IPv6 54677985 0t0 TCP *:1197 (LISTEN)
服务端 Spring 配置:
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="MyRmiService" />
<property name="service" ref="myService" />
<property name="serviceInterface" value="package.MyService" />
<property name="registryPort" value="${my.rmi.port}" />
</bean>
客户端 Spring 配置:
<bean id="remoteService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://${my.rmi.host}:${my.rmi.port}/MyRmiService"/>
<property name="serviceInterface" value="package.MyService"/>
<property name="lookupStubOnStartup" value="false"/>
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
客户端堆栈跟踪,服务失败后lsof
(不报告):
Exception in thread "main" org.springframework.remoting.RemoteLookupFailureException: Lookup of RMI stub failed; nested exception is java.rmi.ConnectException: Connection refused to host: rmiservice.host; nested exception is:
java.net.ConnectException: Connection refused
at org.springframework.remoting.rmi.RmiClientInterceptor.lookupStub(RmiClientInterceptor.java:215)
at org.springframework.remoting.rmi.RmiClientInterceptor.getStub(RmiClientInterceptor.java:237)
at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:257)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy61.serviceMethod(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:191)
at package.Client.main(Client.java:47)
Caused by: java.rmi.ConnectException: Connection refused to host: rmiservice.host; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Naming.java:84)
at org.springframework.remoting.rmi.RmiClientInterceptor.lookupStub(RmiClientInterceptor.java:200)
... 11 more
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
... 17 more