简体   繁体   中英

Socket timeout for remote EJB3 clients in JBOSS EAP 5.1

Invoking a very long-lasting method (> 30 minutes) of a remote EJB I was getting the following socket timeout exception:

...
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)
 ...

Looking at the above stack it is clear that Jboss default timeout for invoking remote EJBs over socket transport is 30 mins (1800000 msecs). I read many topics on the web but I could not find a working solution, even trying RedHat official solution ( https://access.redhat.com/solutions/25149 ).

After some Jboss internals debugging (mainly related to JBoss Remoting module) I came up with the following solution:

--> define (eg by extension) a new org.jboss.remoting.transport.socket.TransportClientFactory that instatiates ClientInvoker with the new desired timeout:

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);
    }
}

--> register this new factory in org.jboss.remoting.InvokerRegistry (eg in a static block):

static {
    InvokerRegistry.registerInvokerFactories("socket", TestSocketClientFactory.class, TransportServerFactory.class);
}

Hope this will help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM