You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS KMS加密解密随机出现EHOSTUNREACH错误求助

问题:AWS KMS短时间连续调用加密解密随机出现EHOSTUNREACH错误

我是AWS新手,使用AWS KMS进行数据加密和解密,Node.js代码如下:

const { KMS } = require('@aws-sdk/client-kms');
const { KmsKeyringNode, buildClient } = require('@aws-crypto/client-node');

const kmsAccessKeyId = process.env.KMS_ACCESS_KEY_ID;
const kmsSecretAccessKey = process.env.KMS_SECRET_ACCESS_KEY;
const kmsGeneratorKeyId = process.env.KMS_GENERATOR_KEY_ID;
const kmsKeyId = process.env.KMS_KEY_ID;

const REGIONS = {
  REGION: 'region-here', // Contains AWS region. Value here is just for illustration purposes.
};

const clientProvider = () => new KMS({ region: REGIONS.REGION, credentials: { accessKeyId: kmsAccessKeyId, secretAccessKey: kmsSecretAccessKey } });
const keyring = new KmsKeyringNode({ generatorKeyId: kmsGeneratorKeyId , clientProvider, keyIds: [kmsKeyId ] });
const { encrypt, decrypt } = buildClient();


/**
 * Convert buffer to string.
 */
const convertU8toString = (u8Arr) => {
  const textDecoder = new TextDecoder();

  const str = textDecoder.decode(u8Arr);

  return str;
};

/**
 * Receives a plaintext message typeof string
 * encrypt the string
 * receive back a buffer
 * convert the buffer to base64
 * return the string-version of the base64.
 */
const encryptData = async (value) => {
  try {
    if (!value) throw new Error('No value provided');

    if (typeof value !== 'string') throw new Error('Only value type of string is supported');

    const { result } = await encrypt(keyring, value);
    const storableMessage = result.toString('base64');

    return storableMessage;
  } catch (err) {
    throw err;
  }
};

/**
 * Receives a base64 encoded message typeof string
 * convert the base64 back to a buffer.
 * decrypt the buffer
 * receive back a buffer
 * return the plaintext message typeof string.
 */
const decryptData = async (value) => {
  try {
    if (!value) throw new Error('No value provided');

    if (typeof value !== 'string') throw new Error('Only value type of string is supported');

    const newBuff = Buffer.from(value, 'base64');
    const { plaintext } = await decrypt(keyring, newBuff);

    return convertU8toString(plaintext);
  } catch (err) {
    throw err; // Our own custom error. Just re-throw.
  }
};

单独执行加密或解密功能正常,但短时间内连续调用encrypt和decrypt方法时,随机出现以下错误:

Error: connect EHOSTUNREACH 52.94.177.94:443
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) {
  errno: -113,
  code: 'EHOSTUNREACH',
  syscall: 'connect',
  address: '52.94.177.94',
  port: 443,
  '$metadata': { attempts: 1, totalRetryDelay: 0 }
}

错误出现后需等待一段时间才能恢复,自动化测试中尤为明显,即使单测test.only也会随机触发。该IP属于AWS,求问题原因及解决方案。


解决方案

问题根源

  1. 客户端实例重复创建:你的clientProvider每次调用都会新建一个KMS客户端,短时间连续请求会生成大量TCP连接,超出系统本地端口限制或AWS端的连接阈值,导致连接失败。
  2. 缺少重试策略:AWS SDK默认重试次数不足,单次连接失败直接抛出错误,没有重试机制应对临时网络波动。

具体修复步骤

1. 复用KMS客户端实例

不要每次请求都创建新客户端,全局初始化一次即可:

// 全局初始化KMS客户端,只创建一次
const kmsClient = new KMS({
  region: REGIONS.REGION,
  credentials: { accessKeyId: kmsAccessKeyId, secretAccessKey: kmsSecretAccessKey },
  // 配置重试策略,增加重试次数
  maxRetries: 3,
  // 配置HTTP连接池,启用长连接
  httpOptions: {
    agent: new (require('https').Agent)({
      keepAlive: true,
      maxSockets: 50, // 根据并发量调整
      maxFreeSockets: 10
    })
  }
});

// 修改clientProvider,返回已创建的实例
const clientProvider = () => kmsClient;

2. 优化密钥环初始化

确保密钥环只初始化一次,避免重复创建资源:

// 全局初始化密钥环
const keyring = new KmsKeyringNode({
  generatorKeyId: kmsGeneratorKeyId,
  clientProvider,
  keyIds: [kmsKeyId]
});
const { encrypt, decrypt } = buildClient();

3. 测试环境优化

  • 测试时避免在每个测试用例中重新初始化客户端/密钥环,使用测试框架的beforeAll/afterAll钩子全局初始化一次。
  • 若测试并发量高,可适当调整maxSockets参数,或添加请求间隔(仅测试临时用,不推荐生产环境)。

额外建议

  • 生产环境优先使用IAM角色而非硬编码Access Key,避免密钥泄露风险。
  • 监控AWS KMS的API调用指标(如Throttles),排查是否存在限流情况。

内容的提问来源于stack exchange,提问作者Jplus2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:13:20