Объяснение проблемы
Я предполагаю, что ваше объяснение о закрытии соединения через брандмауэр через 30 минут является правильным.
Из того, что я вижу, ApacheHTTP-клиент решает, как долго поддерживать текущее соединение, основываясь на ConnectionKeepAliveStrategy
.По умолчанию это org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
, и это будет поддерживать живое соединение до тех пор, пока это рекомендуется заголовком Keep-Alive
в ответах от сервера Elasticsearch, или неопределенно долго, если сервер Elasticsearch не возвращает такой заголовок в ответах.
Я провел несколько тестов, и, по-видимому, Elasticsearch не возвращает ни одного заголовка Keep-Alive
, поэтому в настоящее время соединения повторно используются бесконечно, по крайней мере до тех пор, пока ваша сеть их не убьет.
После подключенияЕсли вы убиты, вы можете надеяться, что вступят в силу автоматические повторные попытки, но они эффективны, только если у вас более одного узла Elasticsearch.Если у вас есть только один узел, и запрос не выполняется, тогда остальной клиент не будет повторять попытку на том же узле.
Таким образом, в общем, ожидаются сбои.Что не так, тот факт, что вы были свидетелями сбоев только с вашим собственным клиентским кодом, но я думаю, что вы, возможно, пропустили некоторые ошибки в журналах?
Решение (надеюсь)
Может быть,HTTP-клиент Apache может автоматически обрабатывать повторное открытие соединений, когда они принудительно закрыты, но я не смог найти такую функцию.
Я не смог найти способ заставить сервер Elasticsearch добавить заголовок Keep-Alive
к его ответам HTTP, либо.
Если вы используете HTTP, а не HTTPS (в этом случае я надеюсь, что это частная сеть), вы сможете настроить сетевую инфраструктуру для вставки таких заголовков в каждое сообщение HTTP,Если вы используете Elasticsearch за прокси-сервером, таким как сервер Apache, вы также должны это сделать.
В противном случае, чтобы явно настроить его на стороне клиента, вы можете использовать расширение org.hibernate.search.elasticsearch.client.spi.ElasticsearchHttpClientConfigurer
точка в Hibernate Search.
WARNING : эта точка расширения является SPI и, кроме того, она экспериментальная, что означает, что она может изменяться несовместимыми способами в любой новой версии Hibernate Search.При следующем обновлении вам, возможно, придется изменить свой код даже для микрообновления.С нашей стороны никаких гарантий.
Создайте реализацию:
package com.acme.config;
import org.hibernate.search.elasticsearch.client.spi.ElasticsearchHttpClientConfigurer;
public class MyHttpConfigurer implements ElasticsearchHttpClientConfigurer {
private static final int KEEP_ALIVE_MS = 20 * 60 * 1000; // 20 minutes
@Override
public void configure(HttpAsyncClientBuilder builder, Properties properties) {
builder.setKeepAliveStrategy( (response, context) -> KEEP_ALIVE_MS );
}
}
Зарегистрируйте свою реализацию, создав файл META-INF/services/org.hibernate.search.elasticsearch.client.spi.ElasticsearchHttpClientConfigurer
с таким содержанием:
com.acme.config.MyHttpConfigurer
..... и все готово.
Запустите приложение один раз в режиме отладки с точкой останова в MyHttpConfigurer
, чтобы проверить его выполнение, и если это так, HTTP-клиент должен автоматически прекратить использование незанятых соединений через 20 минут ивы не должны испытывать ту же проблему снова.
Чтобы ответить на ваши вопросы
- Может кто-нибудь объяснить количество соединений между HibernateSearch и ES (я думал, что по умолчанию установлено значение 20или 2 в зависимости от кластера ES или нет) и если соединения используются в циклическом или случайном порядке?
Из документации:
hibernate.search.default.elasticsearch.max_total_connection 20 (по умолчанию)
hibernate.search.default.elasticsearch.max_total_connection_per_route 2 (по умолчанию)
Не зависитот того, является ли ES кластеризованным или нет.Это зависит от того, сколько узлов / маршрутов знают клиенты.Если автоматическое обнаружение отключено (hibernate.search.default.elasticsearch.discovery.enabled false
, по умолчанию), узлы, известные клиенту, - это те, которые вы настроили явно.Если он включен, и в кластере более одного узла, клиент может знать больше узлов, чем вы настроили явно.
По умолчанию вы будете использовать не более двух подключений на хост, известных вашемуклиент, но не более 20 соединений.Таким образом, если известно 9 узлов, вы будете использовать не более 18 соединений, если известно 10 узлов, вы будете использовать не более 20 соединений, а если известно 11 или более узлов, вы все равно будете использовать не более 20 соединений.
Будет ли простая повторная попытка вызова RestClient "разбудить" соединение снова?
Насколько я знаю, это должно произойти, но тогда я не знаю, что именно сбрасываетваша связь, поэтому трудно сказать.
Или нам нужно вручную повторно подключить соединение к ES, и если да, то как?
Не думаю, что вам следует делать это самостоятельно.Соединения управляются автоматически на очень низком уровне.Не Hibernate Search, даже не Rest Client, а HTTP-клиентом.
В любом случае, если вы действительно хотите пойти по этому пути, вам придется каким-то образом заполучить HTTP-клиента.Я не знаю как.
Наконец, существует ли существующий параметр поиска в режиме гибернации, который мог бы решить эту проблему, возможно hibernate.search.default.elasticsearch.discovery.enabled или другой?
hibernate.search.default.elasticsearch.discovery.enabled
только поможетесли вам нужно больше соединений и ваш Elasticsearch кластеризован;в вашем случае кажется, что ваши существующие соединения прерываются через определенное время, поэтому даже если вы увеличите количество соединений, вы все равно столкнетесь с той же проблемой.