简体   繁体   English

Elasticsearch Java High-Level REST Client 建立一堆TCP连接,索引数据后不关闭

[英]Elasticsearch Java High-Level REST Client establish a bunch of TCP connection and doesn't close them after indexing data

I have a periodic job that has been run every second (this is configurable).我有一个每秒运行一次的定期作业(这是可配置的)。

In this job, I first create a connection to Elasticsearch server:在这份工作中,我首先创建了一个到 Elasticsearch 服务器的连接:

RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(new HttpHost(address, port, "http")));

Then I check for the existence of a special index called test .然后我检查是否存在名为test的特殊索引。 If it doesn't exist, I create it first.如果它不存在,我会先创建它。

GetIndexRequest indexRequest = new GetIndexRequest();
indexRequest.indices("test");
boolean testIndexIsExists = false;
try {           
     testIndexIsExists = client.indices().exists(indexRequest, RequestOptions.DEFAULT); 
    } catch (IOException ioe) {
    logger.error("Can't check the existence of test index in Elasticsearch!");  
}
if(testIndexIsExists) {
     // bulk request...
} else {
    CreateIndexRequest testIndex = new CreateIndexRequest("test");
    try {   
        testIndex.mapping("doc", mappingConfiguration);
        client.indices().create(testIndex, RequestOptions.DEFAULT);
        // bulk request...  
    } catch (IOException ioe) { 
        logger.error("Can't create test index in Elasticsearch");
    }   
}

And after doing a bulk request that has near 2000 document, I close the Elasticsearch client connection:在做了一个接近 2000 个文档的批量请求之后,我关闭了 Elasticsearch 客户端连接:

client.close();

Java High Level REST Client version: Java 高级 REST 客户端版本:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.4.0</version>
</dependency>

My problem is a bunch of TCP connection that has been established and don't be closed.我的问题是一堆已经建立但没有关闭的 TCP 连接。 These TCP connections occupy all operating system TCP connections over time.这些 TCP 连接会随着时间的推移占用所有操作系统 TCP 连接。

On the other hand, I'm a bit confused.另一方面,我有点困惑。 Should RestHighLevelClient instance be a singleton object for the entire application or I must create a new instance in every job running cycle and close the instance after doing that job? RestHighLevelClient实例应该是整个应用程序的单例对象,还是我必须在每个作业运行周期中创建一个新实例并在完成该作业后关闭该实例?

The high level client is already maintaining a connection pool for you, so I would use it as a singleton.高级客户端已经为您维护了一个连接池,因此我将其用作单例。 Constantly creating and closing connection pools is expensive, and the client and underlying HTTP connection pool are thread safe.不断地创建和关闭连接池代价高昂,而且客户端和底层 HTTP 连接池是线程安全的。 Also, calling close() on the client just delegates to the Apache HTTP client shutdown() method, so you're at the mercy of how they handle cleanup and releasing resources.此外,在客户端上调用close()只是委托给 Apache HTTP 客户端shutdown()方法,因此您受他们如何处理清理和释放资源的支配。

If you're using Spring or some other DI framework, it's easy to create a singleton instance of the client that can be injected as needed.如果您使用的是 Spring 或其他一些 DI 框架,则很容易创建可以根据需要注入的客户端的单例实例。 And you can add the call to client.close() as part of the bean shutdown/destroy lifecycle phase.您可以将调用添加到client.close()作为 bean 关闭/销毁生命周期阶段的一部分。

Quick example using Spring Boot:使用 Spring Boot 的快速示例:

@Configuration
@ConditionalOnClass(RestHighLevelClient.class)
public class ElasticSearchConfiguration {

    @Value("${elasticsearch.address}")
    String address;

    @Value("${elasticsearch.port}")
    int port;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(address, port, "http")));
    }
}

Note: In this case Spring will automatically detect that the bean has a close method and call it for you when the bean is destroyed.注意:在这种情况下,Spring 会自动检测到 bean 有close方法,并在 bean 销毁时为您调用它。 Other frameworks may require you to specify how shutdown should be handled.其他框架可能要求您指定应如何处理关闭。

RestHighLevelClient should generally be singleton, unless you have a good reason. RestHighLevelClient通常应该是单例的,除非你有充分的理由。 For example if your job is running every hour and not a minute it might make sense to create new instance and close it after the job.例如,如果您的作业每小时而不是每分钟运行一次,则创建新实例并在作业完成后关闭它可能是有意义的。

If you are sure you are calling the close() in all cases (eg you haven't missed any exceptions) then my next guess is bug in the elastic client.如果您确定在所有情况下都调用close() (例如您没有错过任何异常),那么我的下一个猜测是弹性客户端中的错误。

It look like they are forgetting to consume the response in the exists call: https://github.com/elastic/elasticsearch/blob/v6.4.0/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java#L1419看起来他们忘记在存在调用中使用响应: https : //github.com/elastic/elasticsearch/blob/v6.4.0/client/rest-high-level/src/main/java/org/elasticsearch /client/RestHighLevelClient.java#L1419

Are you able to test without the exists call?你能在没有exists调用的情况下进行测试吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ElasticSearch 多词查询与 Java 高级 REST 客户端 - ElasticSearch Multi Term Query With Java High-Level REST Client Elasticsearch 高层 REST 客户端连接失败 https - Elasticsearch high-level REST client fails to connect over https 直接关闭TCP连接-不关闭更多高层是否正确? - Is it correct to close TCP connection directly - without closing more high-level layer? 如何使用ElasticSearch rest高级客户端按任意字段中的任何单词进行搜索? - How to search by any word in any field with ElasticSearch rest high-level client? 如何在来自 Elasticsearch Java 高级客户端 6.8 的响应中仅获取失败的文档 - How to get only failed documents in the response from Elasticsearch Java High-Level Client 6.8 Elasticsearch高级Rest Client Java排序不正常 - Elasticsearch High Level Rest Client Java sorting not working properly ElasticSearch Java高级Rest客户端:建议搜索 - ElasticSearch Java high Level Rest Client: Suggest-search ElasticSearch Java 高级 REST 客户端:过滤文档和或查询 - ElasticSearch Java High Level REST Client: filter documents and or query ElasticSearch Rest 高级客户端重新映射错误 - ElasticSearch Rest High Level Client remapping wrong Elasticsearch Java 高级 Rest 客户端(已弃用)VS Java 客户端 API - Elasticsearch Java High Level Rest client (deprecated) VS Java Client API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM