我有一个使用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设置了什么数字,真正的连接总是超过数字。
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对象时可能会发生错误,但这在我的情况下不适用。怎么会发生这种情况,解决方案是什么?
提前致谢。
答案 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。