高级配置

编辑

客户端支持许多配置选项,用于设置和管理连接,配置日志记录,自定义传输库等等。

设置主机

编辑

连接到特定的 Elasticsearch 主机

Elasticsearch::Client.new(host: 'search.myserver.com')

连接到具有特定端口的主机

Elasticsearch::Client.new(host: 'myhost:8080')

连接到多个主机

Elasticsearch::Client.new(hosts: ['myhost1', 'myhost2'])

除了字符串,您还可以将主机信息作为哈希数组传递

Elasticsearch::Client.new(hosts: [ { host: 'myhost1', port: 8080 }, { host: 'myhost2', port: 8080 } ])

指定多个主机时,您可能需要启用 retry_on_failureretry_on_status 选项,以便在另一个节点上执行失败的请求(请参阅失败时重试)。

公共 URL 部分(方案、HTTP 身份验证凭据、URL 前缀等)会自动处理

Elasticsearch::Client.new(url: 'https://username:[email protected]:4430/search')

您可以传递以逗号分隔的多个 URL

Elasticsearch::Client.new(urls: 'https://127.0.0.1:9200,https://127.0.0.1:9201')

配置 URL 的另一种方法是导出 ELASTICSEARCH_URL 变量。

客户端将自动在主机之间使用循环算法(除非您选择或实现不同的连接选择器)。

默认端口

编辑

默认端口是 9200。如果您的主机端口与此默认值不同,请指定一个端口。

如果您使用的是 Elastic Cloud,则默认端口为端口 9243。您必须单独提供您的用户名和密码,以及可选的端口。请参阅Elastic Cloud

日志记录

编辑

要使用默认记录器(Ruby 的 ::Logger 类的实例)将请求和响应记录到标准输出,请将 log 参数设置为 true

Elasticsearch::Client.new(log: true)

您还可以使用 ecs-logging,这是一组库,使您能够将应用程序日志转换为符合Elastic Common Schema 的结构化日志。请参阅Elastic Common Schema (ECS)

要以 Curl 格式跟踪请求和响应,请设置 trace 参数

Elasticsearch::Client.new(trace: true)

您可以自定义默认的记录器或跟踪器

client.transport.logger.formatter = proc { |s, d, p, m| "#{s}: #{m}\n" }
client.transport.logger.level = Logger::INFO

或者,您可以使用自定义的 ::Logger 实例

Elasticsearch::Client.new(logger: Logger.new(STDERR))

您可以将任何符合规范的记录器实现传递给客户端

require 'logging' # https://github.com/TwP/logging/

log = Logging.logger['elasticsearch']
log.add_appenders Logging.appenders.stdout
log.level = :info

client = Elasticsearch::Client.new(logger: log)

APM 集成

编辑

此客户端通过 Elastic APM 代理与 Elastic APM 无缝集成。如果您在代码中使用代理,它会自动捕获客户端请求。如果您使用 elastic-apm v3.8.0 或更高版本,则可以在 config/elastic_apm.yml 中将 capture_elasticsearch_queries 设置为 true,以同时捕获 Elasticsearch 中请求的主体。请参阅此示例

自定义 HTTP 标头

编辑

您可以在客户端的初始化程序上设置自定义 HTTP 标头

client = Elasticsearch::Client.new(
  transport_options: {
    headers:
      {user_agent: "My App"}
  }
)

您还可以将 headers 作为参数传递给任何 API 端点,以便为请求设置自定义标头

client.search(index: 'myindex', q: 'title:test', headers: {user_agent: "My App"})

使用 X-Opaque-Id 标识正在运行的任务

编辑

X-Opaque-Id 标头允许跟踪某些调用,或将某些任务与启动它们的客户端关联(请参阅文档)。要使用此功能,您需要在每次请求时为客户端上的 opaque_id 设置一个 id。例如

client = Elasticsearch::Client.new
client.search(index: 'myindex', q: 'title:test', opaque_id: '123456')

搜索请求包括以下 HTTP 标头

X-Opaque-Id: 123456

您还可以在初始化客户端时为 X-Opaque-Id 设置前缀。如果您使用 X-Opaque-Id,则此前缀会添加到您在每次请求之前设置的 id 的前面。例如

client = Elasticsearch::Client.new(opaque_id_prefix: 'eu-west1_')
client.search(index: 'myindex', q: 'title:test', opaque_id: '123456')

该请求包括以下 HTTP 标头

X-Opaque-Id: eu-west1_123456

设置超时

编辑

对于 Elasticsearch 中的许多操作,HTTP 库的默认超时时间太短。要增加超时时间,您可以使用 request_timeout 参数

Elasticsearch::Client.new(request_timeout: 5*60)

您还可以使用下面记录的 transport_options 参数。

随机化主机

编辑

如果您将多个主机传递给客户端,默认情况下它会以循环方式轮换使用这些主机。当同一客户端在多个进程中运行时(例如,在 Thin 等 Ruby Web 服务器中),它可能会保持“一次”连接到相同的节点。为了防止这种情况,您可以在初始化和重新加载时随机化主机集合

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], randomize_hosts: true)

失败时重试

编辑

当客户端使用多个主机初始化时,在不同的主机上重试失败的请求是有意义的

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: true)

默认情况下,客户端不会重试请求。您可以通过将数字传递给 retry_on_failure 来指定在引发异常之前重试的次数

 Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5)

您还可以使用 retry_on_status 在返回特定状态代码时重试

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503])

这两个参数也可以一起使用

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_status: [502, 503], retry_on_failure: 10)

您还可以设置以毫秒为单位的 delay_on_retry 值。这会在重试之间添加一个等待延迟

 Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], retry_on_failure: 5, delay_on_retry: 1000)

重新加载主机

编辑

默认情况下,Elasticsearch 会动态发现集群中的新节点。您可以在客户端中利用此功能,并定期检查新节点以分散负载。

要检索和使用来自节点信息 API 的信息,并在每次第 10,000 次请求时使用

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_connections: true)

您可以传递一个特定的请求数,在此之后应执行重新加载

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_connections: 1_000)

要在失败时重新加载连接,请使用

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], reload_on_failure: true)

默认情况下,如果重新加载在一秒钟内未完成,则会超时。要更改设置

Elasticsearch::Client.new(hosts: ['localhost:9200', 'localhost:9201'], sniffer_timeout: 3)

当将重新加载主机(“嗅探”)与身份验证一起使用时,请使用主机信息传递方案、用户和密码,或者,为了更清晰,在 http 选项中传递

Elasticsearch::Client.new(
  host: 'localhost:9200',
  http: { scheme: 'https', user: 'U', password: 'P' },
  reload_connections: true,
  reload_on_failure: true
)

连接选择器

编辑

默认情况下,客户端以循环方式轮换连接,使用 Elastic::Transport::Transport::Connections::Selector::RoundRobin 策略。

您可以实现自己的策略来自定义行为。例如,我们有一个“机架感知”策略,该策略首选具有特定属性的节点。仅当这些节点不可用时,该策略才使用其他节点

class RackIdSelector
  include Elastic::Transport::Transport::Connections::Selector::Base

  def select(options={})
    connections.select do |c|
      # Try selecting the nodes with a `rack_id:x1` attribute first
      c.host[:attributes] && c.host[:attributes][:rack_id] == 'x1'
    end.sample || connections.to_a.sample
  end
end

Elasticsearch::Client.new hosts: ['x1.search.org', 'x2.search.org'], selector_class: RackIdSelector

序列化器实现

编辑

默认情况下,MultiJSON 库用作序列化器实现,它会根据可用的 gem 选择“正确”的适配器。

但是,序列化组件是可插拔的,因此您可以通过包含 Elastic::Transport::Transport::Serializer::Base 模块、实现所需的约定并将其作为 serializer_classserializer 参数传递给客户端来编写自己的序列化器。

异常处理

编辑

该库为各种客户端和服务器错误以及不成功的 HTTP 响应定义了多个异常类,从而可以以所需的粒度捕获特定的异常。

最高级别的异常是 Elastic::Transport::Transport::Error,它针对任何通用客户端或服务器错误而引发。

仅针对服务器错误引发 Elastic::Transport::Transport::ServerError

例如,对于特定于响应的错误,404 响应状态会引发 Elastic::Transport::Transport::Errors::NotFound 异常。

最后,当连接重新加载(“嗅探”)超时时,会引发 Elastic::Transport::Transport::SnifferTimeoutError