如何使用 elastic java 客户端与 aws elasticsearch 服务通信?
How to talk to aws elasticsearch service using elastic java client?
我已经使用 AWS elasticsearch service (Not EC2). It gave me an endpoint https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com/ 设置了一个 elasticsearch 服务器,如果我点击这个端点(注意没有指定端口)我可以获得预期的
{
status: 200,
name: "Mastermind",
cluster_name: "xxxx",
version: {
number: "1.5.2",
build_hash: "yyyyyy",
build_timestamp: "2015-04-27T09:21:06Z",
build_snapshot: false,
lucene_version: "4.10.4"
},
tagline: "You Know, for Search"
}
问题是如何在没有端口号的情况下通过 elasticsearch java 客户端获取它?我得到的示例代码是
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("host1"), 9300));
如果我使用此代码并将 "host1" 替换为我的端点,我将得到 "NoNodeAvailableException"
ps:
我使用的 java 客户端版本是 2.0.0.
编辑
我最终决定使用第 3 方 REST 客户端 Jest。但是布鲁克斯在下面的回答也很有帮助——AWS 确实使用端口 80 来访问 http,使用 443 来访问 https。我猜对我来说是防火墙。
编辑2
AWS ES 服务文档明确表示:
该服务在端口 80 上支持 HTTP,但不支持 TCP 传输。
信不信由你,AWS 不会使用 9200 和 9300 启动 Elasticsearch。它是通过普通的旧端口 80 启动的。
所以,为了演示,试试这个...
curl -XPOST "http://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:80/myIndex/myType" -d '["name":"Edmond"}'
或
curl -XPOST "https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:443/myIndex/myType" -d '["name":"Edmond"}'
它应该回应:
{"_index":"myIndex","_type":"myType","_id":"SOME_ID_#","_version":1,"created":true}
签入 Kibana,您会看到它就在那里。
所以,那么在你的代码中,应该是:
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("xxx-xxxxxxxx.us-west-2.es.amazonaws.com"), 80));
不幸的是,我不知道如何使用传输客户端通过 SSL/HTTPS 加密传输。您可以尝试使用常规 REST 调用,而不是使用 JERSEY。
最后,确保您的 Elasticsearch 访问策略配置正确。大致如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:yyyyyyy:domain/myDomain/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:yyyyyyyyy:domain/myDomain"
}
]
}
注意: 上述访问策略是完全开放的,不推荐用于远程接近生产的任何内容。只是想让你知道....
AWS中的Managed Elastic Search Service目前没有提供传输协议的端口。
这个问题已经在这里回答了,
Elastic Transport client on AWS Managed ElasticSearch1
AWS 论坛中也有关于传输协议的讨论。这里是 link
经过大量搜索,我找到了一个使用 GET 请求的示例,因此我对其进行了一些小改动以允许 POST 请求,以便可以通过 POST 正文提交复杂的查询。该实现可在 https://github.com/dy10/aws-elasticsearch-query-java
除了正确配置对您的 AWS ES 的访问(即不要将其打开到 Public)之外,请确保使用 https(以上代码使用 http;只需在代码中将 http 替换为 https 即可工作)。
另一个看起来很有用但部分实现的是 https://github.com/aws/aws-sdk-java/issues/861
我已经使用 AWS elasticsearch service (Not EC2). It gave me an endpoint https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com/ 设置了一个 elasticsearch 服务器,如果我点击这个端点(注意没有指定端口)我可以获得预期的
{
status: 200,
name: "Mastermind",
cluster_name: "xxxx",
version: {
number: "1.5.2",
build_hash: "yyyyyy",
build_timestamp: "2015-04-27T09:21:06Z",
build_snapshot: false,
lucene_version: "4.10.4"
},
tagline: "You Know, for Search"
}
问题是如何在没有端口号的情况下通过 elasticsearch java 客户端获取它?我得到的示例代码是
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("host1"), 9300));
如果我使用此代码并将 "host1" 替换为我的端点,我将得到 "NoNodeAvailableException"
ps: 我使用的 java 客户端版本是 2.0.0.
编辑 我最终决定使用第 3 方 REST 客户端 Jest。但是布鲁克斯在下面的回答也很有帮助——AWS 确实使用端口 80 来访问 http,使用 443 来访问 https。我猜对我来说是防火墙。
编辑2
AWS ES 服务文档明确表示:
该服务在端口 80 上支持 HTTP,但不支持 TCP 传输。
信不信由你,AWS 不会使用 9200 和 9300 启动 Elasticsearch。它是通过普通的旧端口 80 启动的。
所以,为了演示,试试这个...
curl -XPOST "http://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:80/myIndex/myType" -d '["name":"Edmond"}'
或
curl -XPOST "https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com:443/myIndex/myType" -d '["name":"Edmond"}'
它应该回应: {"_index":"myIndex","_type":"myType","_id":"SOME_ID_#","_version":1,"created":true}
签入 Kibana,您会看到它就在那里。
所以,那么在你的代码中,应该是:
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("xxx-xxxxxxxx.us-west-2.es.amazonaws.com"), 80));
不幸的是,我不知道如何使用传输客户端通过 SSL/HTTPS 加密传输。您可以尝试使用常规 REST 调用,而不是使用 JERSEY。
最后,确保您的 Elasticsearch 访问策略配置正确。大致如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:yyyyyyy:domain/myDomain/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:yyyyyyyyy:domain/myDomain"
}
]
}
注意: 上述访问策略是完全开放的,不推荐用于远程接近生产的任何内容。只是想让你知道....
AWS中的Managed Elastic Search Service目前没有提供传输协议的端口。
这个问题已经在这里回答了,
Elastic Transport client on AWS Managed ElasticSearch1
AWS 论坛中也有关于传输协议的讨论。这里是 link
经过大量搜索,我找到了一个使用 GET 请求的示例,因此我对其进行了一些小改动以允许 POST 请求,以便可以通过 POST 正文提交复杂的查询。该实现可在 https://github.com/dy10/aws-elasticsearch-query-java
除了正确配置对您的 AWS ES 的访问(即不要将其打开到 Public)之外,请确保使用 https(以上代码使用 http;只需在代码中将 http 替换为 https 即可工作)。
另一个看起来很有用但部分实现的是 https://github.com/aws/aws-sdk-java/issues/861