无法间歇性地连接到弹性搜索

时间:2018-04-15 16:34:27

标签: elasticsearch jest

我正在尝试通过Jest Client连接到弹性搜索。

有时,客户端无法连接到弹性搜索群集。

堆栈追踪:

org.apache.http.NoHttpResponseException: search-xxx-yyy.ap-southeast-1.es.amazonaws.com:443 failed to respond at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)

弹性搜索群集属于公共域,因此我不明白为什么客户端无法连接。

此外,问题间歇性地发生,如果我重试请求,它有时会连接。

感谢任何帮助。感谢

1 个答案:

答案 0 :(得分:1)

当JestClient发起http请求时,它将在套接字上调用read()并阻止。当此读取返回-1时,这意味着服务器在客户端等待响应之前或期间关闭了连接。

为什么会发生

NoHttpResponseException的主要原因有两个:

。在客户端尝试向下发送请求之前,连接的服务器端已关闭。

。连接的服务器端在请求过程中关闭连接。

失效连接(连接在请求前关闭)

通常这是一个过时的连接。使用持久性连接时,您可能有个连接闲置在连接池中。如果空闲时间超过服务器或负载平衡器的HTTP保持活动超时时间,则服务器或负载平衡器将由于其空闲而关闭连接。 Jakarta客户端的结构未接收到有关此事件的通知(它不使用NIO),因此连接处于半关闭状态。客户端可以检测到此状态的唯一方法是从套接字读取。因此,当您发送请求时,写入成功,因为套接字仅被关闭一半(写入成功直到您关闭末端),但是随后的读取表明套接字已关闭。这会导致请求失败。

连接在请求中关闭

可能发生此事件的另一个原因是,连接在服务正在使用时实际上已关闭。客户端和服务之间的任何内容都可能会关闭连接,包括负载平衡器,代理或服务前面的HTTP端点。如果您的活动运行时间很长,或者您正在传输大量数据,则出现问题的窗口会更大,并且在请求中间可能会丢失连接。发生这种情况的一个示例是,由于尝试返回大量数据而导致OutOfMemoryException发生后,Java服务器进程退出。您可以通过查看TCP转储以查看在请求进行过程中连接是否关闭,来验证这是否是问题。同样,这种类型的故障通常在发送请求后的一段时间内发生,而陈旧的连接故障总是在发出请求后立即发生。

诊断原因

NoHttpResponseException通常是一个过时的连接(根据我观察到并帮助人们的问题) 当提交请求后总是立即发生故障时,几乎可以肯定的是陈旧的连接是问题所在 如果在等待响应后出现故障的时间很短,那么发出请求时连接就不会失效,并且在请求中间关闭连接 TCPDumps可以更具决定性。您可以看到何时关闭连接(在请求之前或期间)。

可以做什么

使用更好的客户

存在不阻塞的HTTP客户端,它使调用者可以知道何时关闭连接,而不必尝试从连接中读取。

重试失败的请求

如果您的呼叫可以重试(例如,幂等),那么这是一个不错的选择。除过时的连接故障外,它还涵盖了各种瞬态故障。 NoHttpResponseException不一定是陈旧的连接,并且服务可能已收到请求,因此您应注意仅在安全的情况下重试。