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

如何在AWS Lambda中缓存Secrets Manager的PostgreSQL数据库凭证?

缓存AWS Secrets Manager凭证优化Lambda数据库连接

方案1:利用Lambda执行环境持久化特性缓存

Lambda的执行环境在调用结束后会保留数分钟,将凭证和数据库连接池放在全局作用域,即可实现跨调用复用,避免每次请求都调用Secrets Manager。

修改后的代码示例:

const AWS = require('aws-sdk');
const { Pool } = require('pg');

const secretsManager = new AWS.SecretsManager({ region: 'eu-central-1' });
// 全局变量存储缓存的连接池
let dbPool = null;

const getSecret = async (SecretId) => {
    const response = await secretsManager.getSecretValue({ SecretId }).promise();
    return response.SecretString;
};

const initDbPool = async () => {
    const credentials = JSON.parse(await getSecret('database/credentials'));
    return new Pool({
        host: credentials.host,
        port: credentials.port,
        user: credentials.username,
        password: credentials.password,
        database: credentials.database
    });
};

exports.handler = async (event) => {
    // 如果没有缓存的连接池,初始化后缓存
    if (!dbPool) {
        dbPool = await initDbPool();
    }
    const client = await dbPool.connect();

    // 执行数据库操作...
    
    client.release(); // 记得释放连接回池
};

说明:

  • 全局的dbPool只会在第一次调用时初始化,后续复用同一个连接池
  • 连接池的复用不仅减少了Secrets Manager的调用,还降低了数据库连接的创建开销

方案2:带过期时间的内存缓存(适配凭证轮换场景)

如果需要定期更新凭证,可给缓存添加过期时间,确保在凭证更新后能及时获取新值:

const AWS = require('aws-sdk');
const { Pool } = require('pg');

const secretsManager = new AWS.SecretsManager({ region: 'eu-central-1' });
let cachedCredentials = null;
let cacheExpiry = 0;
const CACHE_TTL = 3600000; // 缓存1小时,单位毫秒

const getSecret = async (SecretId) => {
    const response = await secretsManager.getSecretValue({ SecretId }).promise();
    return response.SecretString;
};

const getCachedCredentials = async () => {
    const now = Date.now();
    // 检查缓存是否过期或未初始化
    if (!cachedCredentials || now > cacheExpiry) {
        cachedCredentials = JSON.parse(await getSecret('database/credentials'));
        cacheExpiry = now + CACHE_TTL;
    }
    return cachedCredentials;
};

const initDbPool = async () => {
    const credentials = await getCachedCredentials();
    return new Pool({
        host: credentials.host,
        port: credentials.port,
        user: credentials.username,
        password: credentials.password,
        database: credentials.database
    });
};

// 全局连接池
let dbPool = null;

exports.handler = async (event) => {
    if (!dbPool) {
        dbPool = await initDbPool();
    }
    const client = await dbPool.connect();

    // 执行数据库操作...
    
    client.release();
};

说明:

  • 缓存过期时间可根据凭证轮换策略调整,比如设置为1小时或更短
  • 即使连接池已初始化,后续如果缓存过期,新的连接会使用更新后的凭证(注意:已存在的连接会继续使用旧凭证,直到连接被释放重建)

关键注意事项

  • 确保Lambda角色拥有secretsmanager:GetSecretValue权限,否则无法获取凭证
  • 若需要凭证更新后立即生效,可缩短缓存TTL,或结合Secrets Manager的事件通知触发Lambda更新缓存
  • 合理配置连接池参数(如max连接数),避免超出数据库的连接上限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:35:20