Elasticsearch Java REST-клиент высокого уровня Установите связку TCP-соединения и не закрывайте эти соединения после помещения данных - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть периодическое задание, которое запускается каждую секунду (это настраивается).

В этой работе я сначала создаю соединение с сервером Elasticsearch:

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

Затем я проверяю наличие специального индекса с именем test.Если он не существует, я сначала создаю его.

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");
    }

}

И после выполнения массового запроса с документом около 2000 я закрываю соединение в этом задании:

client.close();

Версия клиента высокого уровня Java REST:

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

Моя проблема - набор TCP-соединений, которые были установлены и не были закрыты.Эти TCP-соединения со временем занимают все TCP-соединения операционной системы.

С другой стороны, я немного запутался.Должен ли RestHighLevelClient экземпляр быть одноэлементным объектом для всего приложения, или я должен создавать новый экземпляр в каждом цикле выполнения задания и закрывать экземпляр после выполнения этого задания?

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

RestHighLevelClient обычно должно быть одноразовым, если у вас нет веских причин.Например, если ваша работа выполняется каждый час, а не минуту, возможно, имеет смысл создать новый экземпляр и закрыть его после задания.

Если вы уверены, что вызываете close() во всех случаях (например,вы не пропустили ни одного исключения), тогда мое следующее предположение - ошибка в эластичном клиенте.

Похоже, что они забывают использовать ответ в вызове exist: https://github.com/elastic/elasticsearch/blob/v6.4.0/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java#L1419

AreВы можете проверить без звонка exists?

0 голосов
/ 06 марта 2019

Клиент высокого уровня уже поддерживает пул соединений для вас, поэтому я бы использовал его как одиночный.Постоянное создание и закрытие пулов соединений обходится дорого, а клиент и базовый пул HTTP-соединений являются поточно-ориентированными.Кроме того, вызов close() на клиенте просто делегирует методу shutdown() клиента Apache HTTP, так что вы можете рассчитывать, как они обрабатывают очистку и освобождают ресурсы.

Если вы используете Spring илиВ какой-то другой структуре DI легко создать одноэлементный экземпляр клиента, который может быть внедрен по мере необходимости.И вы можете добавить вызов к client.close() как часть фазы жизненного цикла завершения / уничтожения компонента.

Быстрый пример с использованием 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")));
    }
}

Примечание: в этом случаеSpring автоматически обнаружит, что у компонента есть метод close, и вызовет его для вас, когда компонент будет уничтожен.Другие структуры могут потребовать, чтобы вы указали, как завершить работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...