JBOSS EAP 5.1中远程EJB3客户端的套接字超时

时间:2014-07-23 14:34:20

标签: java timeout jboss5.x

调用一个非常持久的远程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)
 ...

查看上面的堆栈,很明显,通过套接字传输调用远程EJB的Jboss默认超时为30分钟(1800000毫秒)。 我在网上阅读了很多主题,但我找不到有效的解决方案,甚至尝试使用RedHat官方解决方案(https://access.redhat.com/solutions/25149)。

1 个答案:

答案 0 :(得分:0)

经过一些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);
}

希望这会有所帮助!