java httpclient单例_java-8 – CloseableHttpClient.execute每隔几周就会冻结一次,尽管超时...

我们有一个groovy单例,使用PoolingHttpClientConnectionManager(httpclient:4.3.6),池大小为200,以处理与搜索服务非常高的并发连接并处理xml响应.

尽管已经指定了超时,但它每个月冻结约一次,但在其余时间内运行良好.

下面的groovy单身.方法retrieveInputFromURL似乎阻止在client.execute(get);

@Singleton(strict=false)

class StreamManagerUtil {

// Instantiate once and cache for lifetime of Signleton class

private static PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();

private static CloseableHttpClient client;

private static final IdleConnectionMonitorThread staleMonitor = new IdleConnectionMonitorThread(connManager);

private int warningLimit;

private int readTimeout;

private int connectionTimeout;

private int connectionFetchTimeout;

private int poolSize;

private int routeSize;

PropertyManager propertyManager = PropertyManagerFactory.getInstance().getPropertyManager("sebe.properties")

StreamManagerUtil() {

// Initialize all instance variables in singleton from properties file

readTimeout = 6

connectionTimeout = 6

connectionFetchTimeout =6

// Pooling

poolSize = 200

routeSize = 50

// Connection pool size and number of routes to cache

connManager.setMaxTotal(poolSize);

connManager.setDefaultMaxPerRoute(routeSize);

// ConnectTimeout : time to establish connection with GSA

// ConnectionRequestTimeout : time to get connection from pool

// SocketTimeout : waiting for packets form GSA

RequestConfig config = RequestConfig.custom()

.setConnectTimeout(connectionTimeout * 1000)

.setConnectionRequestTimeout(connectionFetchTimeout * 1000)

.setSocketTimeout(readTimeout * 1000).build();

// Keep alive for 5 seconds if server does not have keep alive header

ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {

@Override

public long getKeepAliveDuration(HttpResponse response, HttpContext context) {

HeaderElementIterator it = new BasicHeaderElementIterator

(response.headerIterator(HTTP.CONN_KEEP_ALIVE));

while (it.hasNext()) {

HeaderElement he = it.nextElement();

String param = he.getName();

String value = he.getValue();

if (value != null && param.equalsIgnoreCase

("timeout")) {

return Long.parseLong(value) * 1000;

}

}

return 5 * 1000;

}

};

// Close all connection older than 5 seconds. Run as separate thread.

staleMonitor.start();

staleMonitor.join(1000);

client = HttpClients.custom().setDefaultRequestConfig(config).setKeepAliveStrategy(myStrategy).setConnectionManager(connManager).build();

}

private retrieveInputFromURL (String categoryUrl, String xForwFor, boolean isXml) throws Exception {

URL url = new URL( categoryUrl );

GPathResult searchResponse = null

InputStream inputStream = null

HttpResponse response;

HttpGet get;

try {

long startTime = System.nanoTime();

get = new HttpGet(categoryUrl);

response = client.execute(get);

int resCode = response.getStatusLine().getStatusCode();

if (xForwFor != null) {

get.setHeader("X-Forwarded-For", xForwFor)

}

if (resCode == HttpStatus.SC_OK) {

if (isXml) {

extractXmlString(response)

} else {

StringBuffer buffer = buildStringFromResponse(response)

return buffer.toString();

}

}

}

catch (Exception e)

{

throw e;

}

finally {

// Release connection back to pool

if (response != null) {

EntityUtils.consume(response.getEntity());

}

}

}

private extractXmlString(HttpResponse response) {

InputStream inputStream = response.getEntity().getContent()

XmlSlurper slurper = new XmlSlurper()

slurper.setFeature("http://xml.org/sax/features/validation", false)

slurper.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false)

slurper.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false)

slurper.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)

return slurper.parse(inputStream)

}

private StringBuffer buildStringFromResponse(HttpResponse response) {

StringBuffer buffer= new StringBuffer();

BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

String line = "";

while ((line = rd.readLine()) != null) {

buffer.append(line);

System.out.println(line);

}

return buffer

}

public class IdleConnectionMonitorThread extends Thread {

private final HttpClientConnectionManager connMgr;

private volatile boolean shutdown;

public IdleConnectionMonitorThread

(PoolingHttpClientConnectionManager connMgr) {

super();

this.connMgr = connMgr;

}

@Override

public void run() {

try {

while (!shutdown) {

synchronized (this) {

wait(5000);

connMgr.closeExpiredConnections();

connMgr.closeIdleConnections(10, TimeUnit.SECONDS);

}

}

} catch (InterruptedException ex) {

// Ignore

}

}

public void shutdown() {

shutdown = true;

synchronized (this) {

notifyAll();

}

}

}

我还发现在日志中发现这一点,导致我相信它在等待响应数据时发生

java.net.SocketTimeoutException:通过java.net.SocketInputStream.read(SocketInputStream.java:150)在java.net.SocketInputStream.read(SocketInputStream.java:121)上的java.net.SocketInputStream.socketRead0(Native Method)读取超时)在sun.security.ssl.InputRecord.readFully(InputRecord.java:465)

到目前为止的调查结果:

问题

>这可能是同步问题吗?从我的理解,即使单线程被多个线程访问,唯一的共享数据是缓存的CloseableHttpClient

>这个代码有什么其他根本的错误,可能导致这种行为的方法?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值