连接编辑

此页面包含连接和使用客户端与 Elasticsearch 的必要信息。

本页内容

身份验证编辑

本文档包含代码片段,向您展示如何连接到各种 Elasticsearch 提供商。

Elastic Cloud编辑

如果您使用的是 Elastic Cloud,客户端提供了一种简单的方法,可以通过 cloud 选项连接到它。您必须传递可以在云控制台中找到的云 ID,然后在 auth 选项中传递您的用户名和密码。

连接到 Elastic Cloud 时,客户端默认情况下会自动启用请求和响应压缩,因为它可以显著提高吞吐量。此外,除非另有指定,否则客户端还会将 tls 选项 secureProtocol 设置为 TLSv1_2_method。您仍然可以通过配置它们来覆盖此选项。

使用 Elastic Cloud 时不要启用嗅探,因为节点位于负载均衡器后面,Elastic Cloud 会为您处理所有事情。查看 此处 以了解更多信息。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  cloud: {
    id: '<cloud-id>'
  },
  auth: {
    username: 'elastic',
    password: 'changeme'
  }
})

连接到自管理集群编辑

默认情况下,Elasticsearch 将启用身份验证和 TLS 等安全功能。要连接到 Elasticsearch 集群,您需要配置 Node.js Elasticsearch 客户端以使用 HTTPS 和生成的 CA 证书,以便成功发出请求。

如果您刚开始使用 Elasticsearch,我们建议您阅读有关 配置启动 Elasticsearch 的文档,以确保您的集群按预期运行。

当您第一次启动 Elasticsearch 时,您将在 Elasticsearch 的输出中看到类似于以下内容的明显块(如果已经过去一段时间,您可能需要向上滚动)

-> Elasticsearch security features have been automatically configured!
-> Authentication is enabled and cluster connections are encrypted.

->  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
  lhQpLELkjkrawaBoaz0Q

->  HTTP CA certificate SHA-256 fingerprint:
  a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228
...

根据具体情况,有两种验证 HTTPS 连接的选项,要么使用 CA 证书本身验证,要么通过 HTTP CA 证书指纹验证。

TLS 配置编辑

生成的根 CA 证书可以在 Elasticsearch 配置位置的 certs 目录中找到($ES_CONF_PATH/certs/http_ca.crt)。如果您在 Docker 中运行 Elasticsearch,则有 有关检索 CA 证书的其他文档

无需任何其他配置,您可以指定 https:// 节点 URL,并且将验证用于签署这些请求的证书。要关闭证书验证,您必须在顶级配置中指定一个 tls 对象,并将 rejectUnauthorized: false 设置为 false。默认的 tls 值与 Node.js 的 tls.connect() 使用的值相同。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  auth: {
    username: 'elastic',
    password: 'changeme'
  },
  tls: {
    ca: fs.readFileSync('./http_ca.crt'),
    rejectUnauthorized: false
  }
})

CA 指纹编辑

您可以通过提供 caFingerprint 选项来配置客户端,使其仅信任由特定 CA 证书签名的证书(CA 证书固定)。这将验证已签署服务器证书的 CA 证书的指纹是否与提供的指纹值匹配。您必须配置 SHA256 摘要。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://example.com'
  auth: { ... },
  // the fingerprint (SHA256) of the CA certificate that is used to sign
  // the certificate that the Elasticsearch node presents for TLS.
  caFingerprint: '20:0D:CA:FA:76:...',
  tls: {
    // might be required if it's a self-signed certificate
    rejectUnauthorized: false
  }
})

可以使用 openssl x509 和证书文件来计算证书指纹

openssl x509 -fingerprint -sha256 -noout -in /path/to/http_ca.crt

如果您无法访问 Elasticsearch 生成的 CA 文件,可以使用以下脚本使用 openssl s_client 输出 Elasticsearch 实例的根 CA 指纹

# Replace the values of 'localhost' and '9200' to the
# corresponding host and port values for the cluster.
openssl s_client -connect localhost:9200 -servername localhost -showcerts </dev/null 2>/dev/null \
  | openssl x509 -fingerprint -sha256 -noout -in /dev/stdin

openssl x509 的输出将类似于以下内容

SHA256 Fingerprint=A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28

在未启用安全的情况下连接编辑

不建议在未启用安全的情况下运行 Elasticsearch。

如果您的集群配置了 显式禁用的安全功能,那么您可以通过 HTTP 连接

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'http://example.com'
})

身份验证策略编辑

以下列出了所有支持的身份验证策略。

ApiKey 身份验证编辑

您可以通过 auth 选项传递 apiKey 参数来使用 ApiKey 身份验证。 apiKey 参数可以是 base64 编码的字符串,也可以是包含您可以从 创建 API 密钥端点 获得的值的对象。

如果您同时提供基本身份验证凭据和 ApiKey 配置,则 ApiKey 优先。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  auth: {
    apiKey: 'base64EncodedKey'
  }
})
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  auth: {
    apiKey: {
      id: 'foo',
      api_key: 'bar'
    }
  }
})

Bearer 身份验证编辑

您可以通过 auth 选项传递 bearer 令牌参数来提供您的凭据。适用于 服务帐户令牌。请注意,它不处理自动令牌刷新。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  auth: {
    bearer: 'token'
  }
})

基本身份验证编辑

您可以通过 auth 选项传递 usernamepassword 参数来提供您的凭据。

如果您同时提供基本身份验证凭据和 Api Key 配置,则 Api Key 优先。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  auth: {
    username: 'elastic',
    password: 'changeme'
  }
})

否则,您可以在节点 URL 中提供您的凭据。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'https://username:password@localhost:9200'
})

用法编辑

使用客户端非常简单,它支持 Elasticsearch 的所有公共 API,并且每个方法都公开相同的签名。

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  cloud: { id: '<cloud-id>' },
  auth: { apiKey: 'base64EncodedKey' }
})

const result = await client.search({
  index: 'my-index',
  query: {
    match: { hello: 'world' }
  }
})

每个 API 调用的返回值都是来自 Elasticsearch 的响应主体。如果您需要访问其他元数据,例如状态代码或标头,则必须在请求选项中指定 meta: true

const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  cloud: { id: '<cloud-id>' },
  auth: { apiKey: 'base64EncodedKey' }
})

const result = await client.search({
  index: 'my-index',
  query: {
    match: { hello: 'world' }
  }
}, { meta: true })

在这种情况下,结果将是

{
  body: object | boolean
  statusCode: number
  headers: object
  warnings: [string],
  meta: object
}

当您使用 HEAD API 时,主体是一个布尔值。

中止请求编辑

如果需要,您可以使用 AbortController 标准中止正在运行的请求。

如果您中止请求,请求将失败,并出现 RequestAbortedError 错误。

const AbortController = require('node-abort-controller')
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  cloud: { id: '<cloud-id>' },
  auth: { apiKey: 'base64EncodedKey' }
})

const abortController = new AbortController()
setImmediate(() => abortController.abort())

const result = await client.search({
  index: 'my-index',
  query: {
    match: { hello: 'world' }
  }
}, { signal: abortController.signal })

特定于请求的选项编辑

如果需要,您可以在第二个对象中传递特定于请求的选项

const result = await client.search({
  index: 'my-index',
  body: {
    query: {
      match: { hello: 'world' }
    }
  }
}, {
  ignore: [404],
  maxRetries: 3
})

支持的特定于请求的选项是

ignore

[number] -  对于此请求,不应将哪些 HTTP 状态代码视为错误。
默认值: null

requestTimeout

number - 请求的毫秒级最大请求超时,它会覆盖客户端默认值。
默认值: 30000

maxRetries

number - 请求的最大重试次数,它会覆盖客户端默认值。
默认值: 3

compression

string, boolean - 为请求启用主体压缩。
选项: false, 'gzip'
默认值: false

asStream

boolean - 不返回解析后的主体,而是返回原始 Node.js 数据流。
默认值: false

headers

object - 请求的自定义标头。
默认值: null

querystring

object - 请求的自定义查询字符串。
默认值: null

id

any - 自定义请求 ID。(覆盖顶级请求 ID 生成器)
默认值: null

context

any - 每个请求的自定义对象。(您可以使用它将数据传递给客户端的事件)
默认值: null

maxResponseSize

number - 配置后,它会验证未压缩的响应大小是否低于配置的数字,如果高于该数字,它将中止请求。它不能高于 buffer.constants.MAX_STRING_LENTGH
默认值: null

maxCompressedResponseSize

number - 配置后,它会验证压缩后的响应大小是否低于配置的数字,如果高于该数字,它将中止请求。它不能高于 buffer.constants.MAX_LENTGH
默认值: null

signal

AbortSignal - 允许请求中止的 AbortSignal 实例。
默认值: null

在函数即服务环境中使用客户端编辑

本节说明了在函数即服务 (FaaS) 环境中利用 Elasticsearch 客户端的最佳实践。最具影响力的优化是在函数外部,即全局范围内初始化客户端。这种做法不仅可以提高性能,还可以启用后台功能,例如 嗅探。以下示例提供了最佳实践的框架。

GCP Cloud Functions编辑

'use strict'

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
  // client initialisation
})

exports.testFunction = async function (req, res) {
  // use the client
}

AWS Lambda编辑

'use strict'

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
  // client initialisation
})

exports.handler = async function (event, context) {
  // use the client
}

Azure Functions编辑

'use strict'

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
  // client initialisation
})

module.exports = async function (context, req) {
  // use the client
}

用于评估这些建议的资源

通过代理连接编辑

v7.10.0中添加

如果您需要通过 http(s) 代理连接到 Elasticsearch,客户端开箱即用地提供了一个方便的配置来帮助您。在幕后,它使用 hpagent 模块。

在 8.0+ 版本的客户端中,默认的 Connection 类型设置为 UndiciConnection,它不支持代理配置。要使用代理,您需要使用 @elastic/transport 中的 HttpConnection 类。

import { HttpConnection } from '@elastic/transport'

const client = new Client({
  node: 'https://127.0.0.1:9200',
  proxy: 'https://127.0.0.1:8080',
  Connection: HttpConnection,
})

也支持基本身份验证

const client = new Client({
  node: 'https://127.0.0.1:9200',
  proxy: 'http:user:pwd@//127.0.0.1:8080',
  Connection: HttpConnection,
})

如果您通过非 http(s) 代理(例如 socks5pac)连接,您可以使用 agent 选项来配置它。

const SocksProxyAgent = require('socks-proxy-agent')
const client = new Client({
  node: 'https://127.0.0.1:9200',
  agent () {
    return new SocksProxyAgent('socks://127.0.0.1:1080')
  },
  Connection: HttpConnection,
})

错误处理编辑

客户端公开各种错误对象,您可以使用这些对象来增强您的错误处理。您可以在客户端的 errors 键中找到所有错误对象。

const { errors } = require('@elastic/elasticsearch')
console.log(errors)

您可以在下表中找到客户端导出的错误。

错误

描述

属性

ElasticsearchClientError

每个错误都继承自此类,它是客户端生成的 basic 错误。

  • name - string
  • message - string

TimeoutError

当请求超过 requestTimeout 选项时生成。

  • name - string
  • message - string
  • meta - object,包含有关请求的所有信息

ConnectionError

当请求期间发生错误时生成,它可能是连接错误或数据流格式错误。

  • name - string
  • message - string
  • meta - object,包含有关请求的所有信息

RequestAbortedError

如果用户调用 request.abort() 方法,则生成。

  • name - string
  • message - string
  • meta - object,包含有关请求的所有信息

NoLivingConnectionsError

鉴于配置,ConnectionPool 无法为该请求找到可用的 Connection。

  • name - string
  • message - string
  • meta - object,包含有关请求的所有信息

SerializationError

如果序列化失败,则生成。

  • name - string
  • message - string
  • data - object,要序列化的对象

DeserializationError

如果反序列化失败,则生成。

  • name - string
  • message - string
  • data - string,要反序列化的字符串

ConfigurationError

如果配置或参数格式错误,则生成。

  • name - string
  • message - string

ResponseError

当出现 4xx5xx 响应时生成。

  • name - string
  • message - string
  • meta - object,包含有关请求的所有信息
  • body - object,响应正文
  • statusCode - object,响应头
  • headers - object,响应状态码

保持活动连接编辑

默认情况下,客户端使用持久性保持活动连接,以减少为每个 Elasticsearch 请求创建新 HTTP 连接的开销。如果您使用默认的 UndiciConnection 连接类,它会维护一个包含 256 个连接的池,保持活动时间为 10 分钟。如果您使用旧的 HttpConnection 连接类,它会维护一个包含 256 个连接的池,保持活动时间为 1 分钟。

如果您需要禁用保持活动连接,您可以使用您首选的 HTTP 代理选项 覆盖 HTTP 代理。

const client = new Client({
  node: 'https://127.0.0.1:9200',
  // the function takes as parameter the option
  // object passed to the Connection constructor
  agent: (opts) => new CustomAgent()
})

或者,您可以完全禁用 HTTP 代理

const client = new Client({
  node: 'https://127.0.0.1:9200',
  // Disable agent and keep-alive
  agent: false
})

关闭客户端的连接编辑

如果您想关闭由客户端实例管理的所有打开的连接,请使用 close() 函数

const client = new Client({
  node: 'https://127.0.0.1:9200'
});
client.close();

自动产品检查编辑

从 v7.14.0 开始,客户端在第一次调用之前执行必需的产品检查。此预检产品检查允许客户端确定它正在与其通信的 Elasticsearch 版本。产品检查需要向服务器发送一个额外的 HTTP 请求,作为请求管道的一部分,在发送主要 API 调用之前。在大多数情况下,这将在客户端发送的第一个 API 调用期间成功。产品检查完成后,不会为后续 API 调用发送任何其他产品检查 HTTP 请求。