[英]OutOfMemoryError with elasticsearch REST Java client via apache http nio
我們正在使用Elasticsearch REST Java客戶端(我們在Java 7上,因此不能使用普通的Elasticsearch Java客戶端)與我們的Elasticsearch服務器進行交互。 除了我們嘗試對約130萬個文檔進行初始索引編制外,所有其他方法都可以正常工作。 這運行了一段時間,但經過幾十萬份文檔,我們得到了
20/06 21:27:33,153 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) Exception in thread "pool-837116-thread-1" java.lang.OutOfMemoryError: unable to create new native thread
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.start0(Native Method)
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.start(Thread.java:693)
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:334)
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:194)
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
20/06 21:27:33,155 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.run(Thread.java:724)
其次是
java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED
at org.apache.http.util.Asserts.check(Asserts.java:46)
at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase.ensureRunning(CloseableHttpAsyncClientBase.java:90)
at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:123)
at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:343)
at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:325)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:218)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:191)
如您所見,Elasticsearch REST客戶端正在使用apache http nio。 我發現奇怪的是,Nio庫正在為每個單個請求(或連接?)創建一個線程。 從上面的日志中,您可以看到線程(pool-837116-thread-1)。 還有許多I / O調度程序線程,其數量在不斷增加。
但是,活動線程的總數似乎並沒有太大變化。 因此,似乎不是重用線程,而是為每個連接周期創建了一個(或實際上兩個)新線程。 上載基本上是:
1.創建客戶
restClient = RestClient.builder(new HttpHost(host.getHost(),host.getPort(),host.getProtocol())/*,new HttpHost(host.getHost(),host.getPort()+1,host.getProtocol())*/)
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setDefaultCredentialsProvider(credsProvider)
}
}).setMaxRetryTimeoutMillis(30000).build();
2.使用json正文發送請求並關閉客戶端
try{
HttpEntity entity = new NStringEntity(json,ContentType.APPLICATION_JSON);
Response indexResponse = restClient.performRequest("PUT", endpoint, parameters,entity,header);
log.debug("Response #0 #1", indexResponse,indexResponse.getStatusLine());
log.debug("Entity #0",indexResponse.getEntity());
}finally{
if(restClient!=null){
log.debug("Closing restClient #0", restClient);
restClient.close();
}
}
這正常嗎? apache nio為什么不重用線程? Elasticsearch REST客戶端,apache nio或我的代碼是否有問題? 我在restClient上調用close,不確定我還應該做什么。
我試圖在IO Reactor上將線程數設置為1:
restClient = RestClient.builder(new HttpHost(host.getHost(),host.getPort(),host.getProtocol())/*,new HttpHost(host.getHost(),host.getPort()+1,host.getProtocol())*/)
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setDefaultCredentialsProvider(credsProvider)
.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(1).build()); //set to one thread
}
}).setMaxRetryTimeoutMillis(30000).build();
但這並沒有改變有關線程重用的任何內容。
我已經找到了OutOfMemoryError的原因。 盡管我正在嘗試-最終將關閉客戶端的程序段-在該程序段外引發了異常(該程序段無法覆蓋D'oh的所有內容)。 但是創建這么多線程仍然是錯誤的(盡管總線程數並未顯着增加)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.