调用远程EJB的一个非常持久的方法(> 30分钟),我得到以下套接字超时异常:
...
Caused by: org.jboss.remoting.InvocationFailureException: Socket timed out. Waited **1800000** milliseconds for response while calling on InvokerLocator [socket://remote_server:3873/]; nested exception is: java.net.SocketTimeoutException: Read timed out
at org.jboss.remoting.transport.socket.SocketClientInvoker.handleException(SocketClientInvoker.java:137)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.handleOtherException(MicroSocketClientInvoker.java:1079)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:941)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:169)
at org.jboss.remoting.Client.invoke(Client.java:2084)
at org.jboss.remoting.Client.invoke(Client.java:879)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy923.invoke(Unknown Source)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:188)
... 52 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2248)
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2428)
at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2498)
at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2570)
at java.io.ObjectInputStream.read(ObjectInputStream.java:819)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.readVersion(MicroSocketClientInvoker.java:1342)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:895)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:169)
at org.jboss.remoting.Client.invoke(Client.java:2084)
at org.jboss.remoting.Client.invoke(Client.java:879)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
...
查看上面的堆栈,很明显Jboss通过套接字传输调用远程ejb的默认超时是30分钟(1800000 msecs)。我在网上阅读了很多主题,但我找不到一个有效的解决方案,甚至尝试了RedHat官方解决方案(https://access.redhat.com/solutions/25149)。
经过一些Jboss内部调试(主要与Jboss Remoting模块相关),我提出了以下解决方案:
->定义(例如通过扩展)一个新的org.jboss.remoting.transport.socket.TransportClientFactory,用新的期望超时实例化ClientInvoker:
public final class TestSocketClientFactory extends TransportClientFactory {
private static final String SOCKET_TIMEOUT_IN_MILLISECS = "7200000";// 2 hours (jboss default is 30 mins)
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public ClientInvoker createClientInvoker(InvokerLocator locator, Map config) throws IOException {
config.put(SocketClientInvoker.SO_TIMEOUT_FLAG, SOCKET_TIMEOUT_IN_MILLISECS);
return super.createClientInvoker(locator, config);
}
}
->在org.jboss.remoting.InvokerRegistry中注册这个新工厂(例如在静态块中):
static {
InvokerRegistry.registerInvokerFactories("socket", TestSocketClientFactory.class, TransportServerFactory.class);
}
希望这对你有帮助!