连接

编辑

此页面包含连接并使用客户端与 Elasticsearch 的所需信息。

本页内容

身份验证

编辑

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

Elastic Cloud

编辑

如果您使用的是 Elastic Cloud,客户端提供了一种通过 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 客户端以使用生成的 CA 证书通过 HTTPS 进行请求,才能成功发出请求。

如果您刚开始使用 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。默认的 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

string` - 请求的最大请求超时时间(以毫秒为单位),它会覆盖客户端的默认值。
默认值: 30000

retryOnTimeout

boolean - 重试已超时请求。默认值: false

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

opaqueId

string - 设置 X-Opaque-Id HTTP 标头。请参阅 https://elastic.ac.cn/guide/en/elasticsearch/reference/8.16/api-conventions.html#x-opaque-id 默认值: null

maxResponseSize

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

maxCompressedResponseSize

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

signal

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

meta

boolean - 不返回正文,而是返回包含 bodystatusCodeheadersmeta 键的对象
默认值false

redaction

object - 用于从错误元数据中删除潜在敏感数据的选项。请参阅 删除潜在敏感数据

retryBackoff

(min: number, max: number, attempt: number) => number; - 计算在下次请求重试之前休眠多长时间(以秒为单位)的函数
默认值: 使用带有抖动的指数退避的内置函数。

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

编辑

本节说明在函数即服务 (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

所有错误都继承自此类,它是客户端生成的**基本**错误。

  • 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

根据配置,连接池无法为此请求找到可用的连接。

  • 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 版本开始,客户端会在第一次调用之前执行必要的 product check(产品检查)。此预检产品检查允许客户端确定它正在与其通信的 Elasticsearch 版本。产品检查需要在发送主要 API 调用之前,将一个额外的 HTTP 请求发送到服务器作为请求管道的一部分。在大多数情况下,这将在客户端发送的第一个 API 调用期间成功完成。产品检查完成后,后续 API 调用将不会再发送产品检查 HTTP 请求。