ElasticSearch 和 Apache HttpAsyncClient [英] ElasticSearch and Apache HttpAsyncClient
问题描述
我正在尝试将 ElasticSearch REST API 与 Java Apache HttpAsyncClient
库一起使用.我想使用持久管道连接.这是一些测试代码(输出在注释中):
I'm trying to use ElasticSearch REST API with Java Apache HttpAsyncClient
library. I want to use persistent pipelining connection. Here is some test code (output is in comments):
@Test
public void testEsPipeliningClient() throws IOException, ExecutionException, InterruptedException
{
testPost(HttpAsyncClients.createDefault());
//201: {"_index":"test_index","_type":"test_type","_id":"AVIHYGnqdqqg_TAHm4ix","_version":1,"_shards":{"total":2,"successful":1,"failed":0},"created":true}
testPost(HttpAsyncClients.createPipelining());
//400: No handler found for uri [http://127.0.0.1:9200/test_index/test_type] and method [POST]
}
private void testPost(CloseableHttpAsyncClient client) throws ExecutionException, InterruptedException, IOException
{
client.start();
HttpPost request = new HttpPost("http://127.0.0.1:9200/test_index/test_type");
request.setEntity(new StringEntity("{\"some_field\": \"some_value\"}"));
Future<HttpResponse> responseFuture = client.execute(request, null);
HttpResponse response = responseFuture.get();
System.err.println(response.getStatusLine().getStatusCode() + ": " + EntityUtils.toString(response.getEntity()));
}
我不明白,为什么它可以与 HttpAsyncClients.createDefault()
客户端一起正常工作,但不能与 HttpAsyncClients.createPipelining()
一起使用.我也无法理解这两种创建方法之间的区别.
I can't understand, why it works fine with HttpAsyncClients.createDefault()
client, but doesn't work with HttpAsyncClients.createPipelining()
. Also I can't understand the difference between these two creation methods.
为什么我在使用createPipelining()
时会得到错误响应?
Why do I get error response when I use createPipelining()
?
我试图查看与 https://httpbin.org/post 的区别,但它显示了相同的内容两种选择的结果.我使用默认的 ElasticSearch 设置.
I tried to see the difference with https://httpbin.org/post but it showed me the same result with both options. I use default ElasticSearch settings.
谢谢!
UPD1
我尝试使用 PUT
文档 (PUT http://127.0.0.1/test_index/test_type/
) 请求,结果相同 - 它有效createDefault()
很好,但是在使用 createPipelining()
时我遇到了类似的错误 - 没有找到处理程序 <...>.
I tried with PUT
document (PUT http://127.0.0.1/test_index/test_type/<doc id>
) request with the same result - it works fine with createDefault()
but I got similar error when do it with createPipelining()
- No handler was found <...>.
但是当我尝试执行创建索引的请求 (PUT http://127.0.0.1/
) 时,还有另一个错误.看下面的代码:
But when I try to execute request to create index (PUT http://127.0.0.1/<index name>
) there is another error. See the code below:
@Test
public void testEsPipeliningClient() throws IOException, ExecutionException, InterruptedException
{
testCreateIndex(HttpAsyncClients.createDefault());
//200: {"acknowledged":true}
testCreateIndex(HttpAsyncClients.createPipelining());
//400: {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"failed to parse, document is empty"}],"type":"mapper_parsing_exception","reason":"failed to parse, document is empty"},"status":400}
}
private void testCreateIndex(CloseableHttpAsyncClient client) throws ExecutionException, InterruptedException, IOException
{
client.start();
HttpPut request = new HttpPut("http://127.0.0.1:9200/" + RandomStringUtils.randomAlphabetic(8).toLowerCase());
Future<HttpResponse> responseFuture = client.execute(request, null);
HttpResponse response = responseFuture.get();
System.err.println(response.getStatusLine().getStatusCode() + ": " + EntityUtils.toString(response.getEntity()));
}
正如我在 本文档页面所见 ElasticSearch 默认支持 HTTP 流水线.也许我需要在 ES 设置中更改什么?
As I can see at this documentation page ElasticSearch supports HTTP pipelining by default. Maybe there anything I need to change in ES settings?
UPD2
以下是 UPD1 部分中具有不同日志设置的代码的一些连线日志:
Here are some wire logs for code in UPD1 section with different logging settings:
Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG -Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=INFO
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.impl.conn=DEBUG -Dorg.apache.commons.logging.simplelog.log.org.apache.http.impl.client=DEBUG -Dorg.apache.commons.logging.simplelog.log.org.apache.http.client=DEBUG -Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=DEBUG
UPD3
我只是尝试用 createMinimal() 替换 createDefault(),它导致了与 createPipelining() 相同的错误.MinimalHttpAsyncClient 中的任何想法可能会导致此问题?也许有一种方法可以在没有这个问题的情况下手动创建流水线客户端(使用构建器类)?
I just tried to replace createDefault() with createMinimal() and it caused the same error that createPipelining(). Any ideas what in MinimalHttpAsyncClient may cause this problem? Maybe there is a way I can manually create pipelining client (with builder classes) without this problem?
推荐答案
服务器必须被请求行中的绝对请求 URI 阻塞
The server must be choking on absolute request URI in the request line
[DEBUG] wire - http-outgoing-1 >> "PUT http://127.0.0.1:9200/ydiwdsid HTTP/1.1[\r][\n]"
流水线模式下的 HttpAsyncClient 使用最小的协议处理链.它不会尝试重写请求对象的请求 URI.
HttpAsyncClient in the pipelining mode employs a minimal protocol processing chain. It does not attempt to rewrite the request URI of the request object.
对于您的特定情况,请求流水线似乎没有多大意义.更不用说除非您批量提交请求,否则您甚至不会使用流水线执行.
For your particular case request pipelining does not seem to make a lot of sense. Not to mention that unless you are submitting requests in batches you are not even using pipelined execution.
这篇关于ElasticSearch 和 Apache HttpAsyncClient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!