从突然的java.lang.IllegalStateException中获取此错误:无法执行请求;I/O 反应器状态:已



我正在使用httpcore-nio-4.4.5.jar。我正在使用 elasticsearch RestHighLevelClient 与我们的 elasticsearch 服务器进行交互。这一切都工作正常,除了一段时间我们突然得到I/O反应堆停止错误。

ES方面一切似乎都很好。没有奇怪的行为。

这就是我初始化 ES 客户端的方式。

public synchronized RestHighLevelClient getHighLevelClient() throws ManagerException {
        if (highLevelClient != null) {
            return highLevelClient;
        }
        Map<String, Integer> map = getEsServers(esAddresses);
        HttpHost[] hosts = new HttpHost[map.size()];
        int i = 0;
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            hosts[i++] = new HttpHost(entry.getKey(), entry.getValue(), "http");
            LOGGER.info(entry.getKey() + " " + entry.getValue());
        }
        RestClientBuilder restClientBuilder = RestClient.builder(hosts);
        highLevelClient = customizeHttpClient(restClientBuilder);
        return highLevelClient;
    }
public RestHighLevelClient customizeHttpClient(RestClientBuilder restClientBuilder) {
        Header[] defaultHeaders = new Header[2];
        defaultHeaders[0] = new BasicHeader("Authorization", "Basic YTph");
        defaultHeaders[1] = new BasicHeader("Accept", "application/json");
        restClientBuilder.setDefaultHeaders(defaultHeaders);
        restClientBuilder.setMaxRetryTimeoutMillis(MAX_RETRY_TIMEOUT_MILLIS);
        restClientBuilder.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder
                .setConnectTimeout(CONNECT_TIMEOUT_MILLIS)
                .setSocketTimeout(SOCKET_TIMEOUT_MILLIS)
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT_MILLIS));
        restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                .setMaxConnPerRoute(MAX_CONN_PER_ROUTE)
                .setMaxConnTotal(MAX_CONN_TOTAL));
        return new RestHighLevelClient(restClientBuilder);
    }

所以基本上首先我得到以下堆栈跟踪

java.lang.IllegalStateException: I/O reactor has been shut down
        at org.apache.http.util.Asserts.check(Asserts.java:34) 
        at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.connect(DefaultConnectingIOReactor.java:224) 
        at org.apache.http.nio.pool.AbstractNIOConnPool.processPendingRequest(AbstractNIOConnPool.java:434) 
        at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:276) 
        at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266) 
        at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363) 
        at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125) 
        at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141) 
        at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:346) 
        at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:328) 
        at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:271) 
        at org.elasticsearch.client.RestHighLevelClient.performRequestAsync(RestHighLevelClient.java:537) 
        at org.elasticsearch.client.RestHighLevelClient.performRequestAsyncAndParseEntity(RestHighLevelClient.java:515) 
        at org.elasticsearch.client.RestHighLevelClient.searchAsync(RestHighLevelClient.java:400) 

之后没有超时,只是连续出现以下异常,直到我重新启动服务器。

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:346)  
    at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:328)  
    at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:271)  
    at org.elasticsearch.client.RestHighLevelClient.performRequestAsync(RestHighLevelClient.java:537)  
    at org.elasticsearch.client.RestHighLevelClient.performRequestAsyncAndParseEntity(RestHighLevelClient.java:515)  
    at org.elasticsearch.client.RestHighLevelClient.searchAsync(RestHighLevelClient.java:400)  ```

我遇到了同样的问题,结果我没有关闭HighLevelRestClient。

请参阅HenningAndersen在 https://discuss.elastic.co/t/request-cannot-be-executed-i-o-reactor-status-stopped/195438/4 的回答:

这听起来类似于 https://github.com/elastic/elasticsearch/issues/45115 141。该问题中的问题是由客户端应用程序代码中的 onFailure 方法引发异常引起的。这会导致连接关闭,后续请求将失败,并在此处报告错误。

我相信如果使用任何通过 ActionListener 报告响应/故障的方法,这也会影响高级客户端(我认为它们的方法名称中都有后缀 Async(。

解决方法是确保不会从 onFailure 方法中引发任何异常

getHighLevelClient() 的条件更改为if (highLevelClient != null && highLevelClient.getLowLevelClient().isRunning())

这意味着如果低级客户端(RestClient(未运行,则应续订对我有用的客户端。

最新更新