3

I have a project that uses JAX-WS, and the implementation is RESTEasy. I know the http connection is an expensive resource and we have heavy web service traffic. so I tried to reuse the connection and promote the performance.

The following is my client side code, and I set the pool size to 20.

public abstract class BaseService{
    protected static ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder();
    static {
            clientBuilder.connectionPoolSize( 20 )
                .establishConnectionTimeout(5000, TimeUnit.MILLISECONDS)
                .socketTimeout(5000, TimeUnit.MILLISECONDS);
    }

    public Client getClient() {
        Client client = clientBuilder.build();
        ...
        return client;
    }
}

A sample service class

public class MyService extends BaseService implements IMyService {
    public Something getSomething(long id){
        return  getClient().target(uri).path("getSomethingById")
                .queryParam("id", id)
                .request().get(Something.class);
    }
}

First, it seemed that RESTEasy didn't really pool the connections and reuse them. I used the netstat to monitor the connections, no matter what number I set for the connectionPoolSize, the real connections always exceed the number. enter image description here

The network communication in RESTEasy is handled by Apache HttpClient, which does support pooling connection by PoolingHttpClientConnectionManager. So my question is there a way to make RESTEasy client to really make use of the pooling?

And another very annoying issue is sometimes the web service call failed because of the connection cann't be allocated, especially when access volume is high.

javax.ws.rs.ProcessingException: Unable to invoke request
    at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287)

The exception stack trace was truncated in the log because of space limit, but I believed the error is caused by IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. I know that error might happen when javax.ws.rs.client.Client object is shared by multi threads, but that's not applicable in my case. How could this happen and what's the solution?

Thanks in advance.

Simon L
  • 173
  • 1
  • 11

1 Answers1

1

Connections are not reused if server (or proxy) requests to close them with "Connection: close" response header. haproxy used to do that before 1.5 unless option http-keep-alive was used. Sometimes even passive close (option httpclose) is used explicitly in haproxy configuration for load balancing, like here How to configure HAProxy to send GET and POST HTTP requests to two different application servers.

Jarek Przygódzki
  • 4,284
  • 2
  • 31
  • 41