java.lang.IllegalStateException: запрос не может быть выполнен; Состояние реактора ввода / вывода: ОСТАНОВЛЕНО
У меня есть служба, которая должна выполнять запросы со скоростью ~5 или более запросов / мин. Этот сервис зависит от Apache AsyncHttpClient. Через каждые несколько минут клиенты сталкиваются с некоторым условием, которое вызывает java.lang.IllegalStateException: запрос не может быть выполнен; Состояние реактора ввода / вывода: ОСТАНОВЛЕН. Все запросы к клиенту начинают сбой с тем же сообщением об исключении. После перезапуска службы этот цикл повторяется.
Отладить эту проблему действительно сложно, так как неожиданно сбой выполнения запроса не вызывает обратного вызова метода fail () в AsyncResponse.
Из того, что я мог собрать, было исправление HTTPCORE-370 в HttpCore NIO, которое решало подобную проблему в 4.3.2. Я использую следующую версию - commons-httpclient-3.1.jar httpasyncclient-4.1.1.jar httpcore-4.4.4.jar httpcore-nio-4.4.4.jar
Все же видя эту проблему. Любая помощь могла бы быть полезна.
4 ответа
Я имел дело с этим же исключением в моем приложении, и я наконец нашел полезное предложение в этом посте - http://httpcomponents.10934.n7.nabble.com/I-O-reactor-status-STOPPED-td29059.html
Вы можете использовать метод #getAuditLog() реактора ввода-вывода, чтобы точно определить, какое исключение вызвало его завершение.
Если вы сохраняете ссылку на IOReactor вашего ConnectionManager, вы можете вызвать этот метод, чтобы получить представление о реальной проблеме:
Оказывается, я делал что-то невероятно глупое в своем собственном коде. Но я не мог понять это, пока не прочитал журнал аудита.
Если вы увидели OutOfMemoryError до этого, попробуйте это
-XX:MaxDirectMemorySize=512M
В моем случае при использовании клиента высокого уровня Elasticsearch это исключение связано с esclient.indexAsync(indexRequest,RequestOptions.DEFAULT,null)
Я исправил это, добавив слушателей действий во все подобные асинхронные запросы
esclient.indexAsync(indexRequest,RequestOptions.DEFAULT,
new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse response) {
}
@Override
public void onFailure(Exception e) {
});
Мы столкнулись с той же проблемой, и после долгих поисков мы обнаружили, что правильный
IOReactorExceptionHandler
необходимо предоставить HttpAsyncClient, чтобы этого избежать. К сожалению, это не очень хорошо описано в документации.
Ниже приведен фрагмент нашего кода, в котором более надежный конструктор клиентов пытается добавить обработчик исключений. Обратите внимание, что исключения IOExceptions все равно остановят реактор ввода-вывода, поскольку они могут указывать на сбои базовой сетевой связи. Вы можете настроить его в соответствии с вашими уникальными сценариями использования.
public RobustCloseableHttpAsyncClientBuilder withDefaultExceptionHandler() {
return withExceptionHandler(
new IOReactorExceptionHandler() {
@Override
public boolean handle(RuntimeException ex) {
logger.error(
"RuntimeException occurs in callback, handled by default exception handler and the I/O reactor will be resumed.",
ex);
return true;
}
@Override
public boolean handle(IOException ex) {
logger.error(
"IOException occurs in callback, handled by default exception handler and the I/O reactor will be stopped.",
ex);
return false;
}
});
}
Прочтите этот отчет о проблеме в elasticsearch на Github, чтобы узнать больше.