ES报错:Request cannot be executed; I/O reactor status: STOPPED

101 阅读1分钟

问题

使用ES过程中遇到一个Request cannot be executed; I/O reactor status: STOPPED 的异常,大概意思是和server端的连接异常终止了。出现时机是偶尔出现,同时多节点的应用服务不是都出现。

主要报错信息是:

Request cannot be executed; I/O reactor status: STOPPED

  • 后端程序处于假死状态,访问其他接口一直转圈,无法响应内容
  • 重启程序之后一切正常
  • 详细报错日志为:

image-20241011103847783

  • 本地IDEA中一次也没有报这个问题
  • 使用JMETER设置50个线程并发访问一个查询大量数据的接口可以稳定复现此问题

原因

程序接口中将一块很大的数据存进JAVA集合中引发了oom,oom异常导致程序宕机,处于假死状态,进而导致 ES-CLIENT 和 ES-SERVER 端的 http 连接异常终止,然后org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase.ensureRunning 方法报异常。

源码

protected void ensureRunning() {
    final Status currentStatus = this.status.get();
    Asserts.check(currentStatus == Status.ACTIVE, "Request cannot be executed; " +
            "I/O reactor status: %s", currentStatus);
}
public static void check(final boolean expression, final String message, final Object arg) {
    if (!expression) {
        throw new IllegalStateException(String.format(message, arg));
    }
}
  • SpringDataElasticsearch 和ES-SERVER 是长链接,只要报了OOM,当前和 ES-SERVER 的连接线程都将报异常,也就是说,虽然OOM只报了一次,但是可能有多个线程都在 Asserts.check 方法中报异常
  • 本地idea无法复现的原因是内存配置不同导致的,本地idea内存给的4g。编辑 run/debug configuration ,设置 VM options 和线上环境相同,使用jemter压测本地idea中跑的程序,也能应该复现此问题

解决

  • 优化接口,解决OOM问题