修复jest的Connection is still allocated异常

/ springboot / 没有评论 / 140浏览

在springboot1.4.5版本下引用jest去访问es,出现Connection is still allocated异常。

异常

java.lang.IllegalStateException: Connection is still allocated
	at org.apache.http.util.Asserts.check(Asserts.java:34)
	at org.apache.http.impl.conn.BasicHttpClientConnectionManager.getConnection(BasicHttpClientConnectionManager.java:251)
	at org.apache.http.impl.conn.BasicHttpClientConnectionManager$1.get(BasicHttpClientConnectionManager.java:202)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at io.searchbox.client.http.JestHttpClient.executeRequest(JestHttpClient.java:118)
	at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:57)

原因

spring-boot-autoconfigure-1.4.5.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/elasticsearch/jest/JestAutoConfiguration.java 默认配置没有启用multiThread支持 jest-2.4.0-sources.jar!/io/searchbox/client/JestClientFactory.java

protected HttpClientConnectionManager getConnectionManager() {
        HttpClientConnectionManager retval;

        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", httpClientConfig.getPlainSocketFactory())
                .register("https", httpClientConfig.getSslSocketFactory())
                .build();

        if (httpClientConfig.isMultiThreaded()) {
            log.info("Using multi thread/connection supporting pooling connection manager");
            final PoolingHttpClientConnectionManager poolingConnMgr = new PoolingHttpClientConnectionManager(registry);

            final Integer maxTotal = httpClientConfig.getMaxTotalConnection();
            if (maxTotal != null) {
                poolingConnMgr.setMaxTotal(maxTotal);
            }
            final Integer defaultMaxPerRoute = httpClientConfig.getDefaultMaxTotalConnectionPerRoute();
            if (defaultMaxPerRoute != null) {
                poolingConnMgr.setDefaultMaxPerRoute(defaultMaxPerRoute);
            }
            final Map<HttpRoute, Integer> maxPerRoute = httpClientConfig.getMaxTotalConnectionPerRoute();
            for (Map.Entry<HttpRoute, Integer> entry : maxPerRoute.entrySet()) {
                poolingConnMgr.setMaxPerRoute(entry.getKey(), entry.getValue());
            }
            retval = poolingConnMgr;
        } else {
            log.info("Using single thread/connection supporting basic connection manager");
            retval = new BasicHttpClientConnectionManager(registry);
        }

        return retval;
    }

修复

升级springboot到1.5.0.M1以上,后者自己修改auto config

protected HttpClientConfig createHttpClientConfig() {
        HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
                this.properties.getUris());
        if (StringUtils.hasText(this.properties.getUsername())) {
            builder.defaultCredentials(this.properties.getUsername(),
                    this.properties.getPassword());
        }
        String proxyHost = this.properties.getProxy().getHost();
        if (StringUtils.hasText(proxyHost)) {
            Integer proxyPort = this.properties.getProxy().getPort();
            Assert.notNull(proxyPort, "Proxy port must not be null");
            builder.proxy(new HttpHost(proxyHost, proxyPort));
        }
        Gson gson = this.gsonProvider.getIfUnique();
        if (gson != null) {
            builder.gson(gson);
        }
        return builder.connTimeout(this.properties.getConnectionTimeout())
                .readTimeout(this.properties.getReadTimeout())
                .multiThreaded(true)
                .build();
    }

设置multiThreaded(true)

doc