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,求问题原因及解决方案。
解决方案
问题根源
- 客户端实例重复创建:你的
clientProvider每次调用都会新建一个KMS客户端,短时间连续请求会生成大量TCP连接,超出系统本地端口限制或AWS端的连接阈值,导致连接失败。 - 缺少重试策略: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
相关产品推荐
相关产品推荐

