【问题标题】:How to talk to aws elasticsearch service using elastic java client?如何使用弹性 java 客户端与 aws elasticsearch 服务通信?
【发布时间】:2016-02-07 02:04:42
【问题描述】:

我已经使用AWS elasticsearch service(不是 EC2)设置了一个弹性搜索服务器。它给了我一个端点https://xxx-xxxxxxxx.us-west-2.es.amazonaws.com/,如果我点击这个端点(注意没有指定端口)我可以得到预期的

{
  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 传输。

【问题讨论】:

  • 如果我的回答满足您的问题,如果您将其标记为正确,我将不胜感激。
  • @Brooks,我仍然无法使用传输客户端连接到 AWS 弹性服务,最后决定使用 Jest。但是您的回答仍然帮助我理解了问题所在。我已经编辑了我的问题,接受了你的回答。如果您找到了完整的解决方案,请编辑您的答案,以便其他人受益。
  • 您好 Edmond,您仍然无法连接吗?您的访问政策是否到位?
  • @Brooks,是的,它已经到位。实际上,我将其设置为向公众开放只是为了开发和测试目的。仍然没有工作。但到目前为止,JEST 一直运行良好。
  • 我假设您将端口更改为 80?明天我会用我的 ES 实例试一试,看看会发生什么。以前从未使用过 JEST,但听起来很整洁。另外,它看起来提供 SSL?我认为仍然需要有办法解密它。

标签: amazon-web-services elasticsearch elasticsearch-java-api amazon-elasticsearch


【解决方案1】:

信不信由你,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"
    }
  ]
}

注意:上述访问策略是完全开放的,不建议用于任何远程接近生产的东西。只是让你知道....

【讨论】:

  • 是的。 curl 在连接到 xxxxxxx.us-west-2.es.amazonaws.com:-9847 时给了我未知的 SSL 协议错误。不知道 9847 是什么。
  • 我认为你可能是对的。我可以通过点击xxx.amazonaws.com:80 得到回复。但我仍然不知道如何在代码中做到这一点。 BTW,InetAddress.getByName(String) 不能取“http”或“https”,否则会报“Unknown host”错误。
  • 啊,抱歉。是的,如果您使用的是 https,那么它将是端口 443。如果您选择使用 http,那么它将是端口 80。我已经相应地更新了我的答案。顺便说一句,请确保您已正确设置了 elasticsearch 的访问策略。我也会为此更新我的答案。
  • 对,我忘了。不幸的是,我不知道如何使用传输客户端进行加密传输。正如我在对答案的最新编辑中提到的那样,您可以轻松地使用带有 JERSEY 的 REST 调用来做到这一点,但显然会失去传输客户端的好处。有一些包装器支持 Elastic Found 的 SSL,但我还没有看到 AWS 的包装器。出于测试目的,我会坚持通过端口 80 保持明文,同时继续寻找加密方法。 Java必须有办法,我就是不知道。
【解决方案2】:

AWS 中的托管弹性搜索服务直到现在才提供传输协议的端口。
这个问题已经在这里回答了,

Elastic Transport client on AWS Managed ElasticSearch1

AWS 论坛中也有关于传输协议的讨论。这是链接

What is the port for the transport protocol ?

【讨论】:

    【解决方案3】:

    经过大量搜索后,我找到了一个使用 GET 请求的示例,因此我对其进行了细微更改以允许 POST 请求,以便可以通过 POST 正文提交复杂的查询。该实现可在https://github.com/dy10/aws-elasticsearch-query-java

    获得

    除了正确配置对您AWS ES的访问(即不要将其公开)外,请确保使用https(上面的代码使用http;只需在代码中将http替换为https即可)。

    另一个有用但部分实现的地方是https://github.com/aws/aws-sdk-java/issues/861

    【讨论】:

    • 这只是一个如何将 HTTP POST 查询发送到 AWS ElasticSearch 服务的示例。 EsQuery.java文件中包含main方法,将4个静态String变量替换为实值后,直接运行即可。
    • 您的评论应该包含在您的回答中。评论是短暂的,可以随时删除。请edit您对缺失信息的回答。
    • 您是否阅读了上面的 cmets 2 行凭据?那些是假证件。它就在那里,所以不太熟悉的人可以很容易地确定那里期望什么样的价值。
    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    相关资源
    最近更新 更多