RESTEasy客户端连接池没有汇集,偶尔“无法调用”

时间:2017-03-13 18:00:22

标签: web-services jax-ws connection-pooling resteasy

我有一个使用JAX-WS的项目,实现是RESTEasy。我知道http连接是一种昂贵的资源,我们有大量的Web服务流量。所以我试图重用连接并提升性能。

以下是我的客户端代码,我将池大小设置为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;
    }
}

示例服务类

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

首先,似乎RESTEasy并没有真正汇集连接并重用它们。我使用netstat来监控连接,无论我为connectionPoolSize设置了什么数字,真正的连接总是超过数字。 enter image description here

RESTEasy中的网络通信由Apache HttpClient处理,它支持PoolingHttpClientConnectionManager的池连接。所以我的问题是有一种方法可以让RESTEasy客户端真正地使用池化吗?

另一个非常恼人的问题是,有时Web服务调用失败,因为无法分配连接,尤其是当访问量很高时。

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

由于空间限制,异常堆栈跟踪在日志中被截断,但我认为错误是由 IllegalStateException引起的:无效使用BasicClientConnManager:仍然分配连接 。我知道当多线程共享javax.ws.rs.client.Client对象时可能会发生错误,但这在我的情况下不适用。怎么会发生这种情况,解决方案是什么?

提前致谢。

1 个答案:

答案 0 :(得分:1)

如果服务器(或代理)请求使用"Connection: close"响应标头关闭它们,则不会重用连接。除非使用option http-keep-alive,否则 haproxy 以前会在1.5之前执行此操作。有时甚至被动关闭(option httpclose)在haproxy配置中明确使用以实现负载平衡,例如此处How to configure HAProxy to send GET and POST HTTP requests to two different application servers