本地通过SSH隧道用AWS SAM连接RDS遇ER_GET_CONNECTION_TIMEOUT超时问题
问题描述
- 本地通过SSH隧道连接AWS RDS实例,执行命令:
ssh -N -L 33336:<rds-host>.us-east-1.rds.amazonaws.com:3306 <username>@<ip> -p <port> -i ~/.ssh/id_rsa - 本地通过AWS SAM运行Lambda API,命令:
sam local start-api --env-vars env.json - Lambda中使用
mariadb连接经SSH隧道转发的RDS,配置代码:const pool = mariadb.createPool({ host: 'host.docker.internal', port: RDS_CONFIG.port || 33306, database: RDS_CONFIG.name || 'db_name', user: RDS_CONFIG.user || 'user', password: RDS_CONFIG.pass || 'pwd', timezone: 'UTC', dateStrings: true, }) - 遇到数据库连接超时错误:
"code":"ER_GET_CONNECTION_TIMEOUT","name":"SqlError","text":"retrieve connection from pool timeout after 10001ms - 已知信息:通过DBeaver经SSH隧道可正常连接RDS;已卸载重装Docker和SAM CLI,问题未解决。
排查与解决方法
1. 核对端口映射一致性
SSH隧道监听的是33336端口,但Lambda配置中默认 fallback 到33306,需先确认env.json里的RDS_CONFIG.port是否正确设置为33336。若环境变量未配置,代码会使用错误端口直接导致连接超时。
2. 验证Docker容器对本地隧道端口的访问性
- 执行以下命令测试容器能否连通宿主机的隧道端口:
若输出包含docker run --rm alpine nc -zv host.docker.internal 33336open则通路正常,否则排查以下两点:- 调整SSH隧道监听范围:默认
-L绑定的是127.0.0.1,仅允许宿主机本地访问。修改SSH命令,让隧道监听所有网卡:ssh -N -L 0.0.0.0:33336:<rds-host>.us-east-1.rds.amazonaws.com:3306 <username>@<ip> -p <port> -i ~/.ssh/id_rsa - 检查宿主机防火墙:确认宿主机防火墙未拦截Docker容器对
33336端口的入站请求,可临时关闭防火墙测试,或添加允许规则。
- 调整SSH隧道监听范围:默认
3. 优化数据库连接池配置
超时提示为连接池获取连接超时,可调整池参数放宽限制:
const pool = mariadb.createPool({ host: 'host.docker.internal', port: 33336, // 确认端口正确 database: RDS_CONFIG.name || 'db_name', user: RDS_CONFIG.user || 'user', password: RDS_CONFIG.pass || 'pwd', timezone: 'UTC', dateStrings: true, connectionLimit: 5, // 适当增加连接池上限 acquireTimeout: 15000, // 延长连接获取超时至15秒 connectTimeout: 10000 // 调整单次连接超时时间 })
4. 直接在SAM容器内测试数据库连接
- 查看SAM启动的容器ID:
docker ps - 进入容器终端:
docker exec -it <container-id> sh - 安装MariaDB客户端(以Alpine镜像为例):
apk add mariadb-client - 执行连接命令测试:
若连接失败,说明容器到宿主机隧道的通路存在问题;若连接成功,则需排查Lambda代码的配置或连接池逻辑。mysql -h host.docker.internal -P 33336 -u <user> -p <db_name>
5. 修改SAM的网络模式
使用host网络模式让容器直接复用宿主机网络,绕过host.docker.internal的解析问题:
sam local start-api --env-vars env.json --docker-network host
注意:切换为host网络后,Lambda中的数据库host需改为127.0.0.1,此时容器直接使用宿主机的回环地址访问隧道。
内容的提问来源于stack exchange,提问作者bmb0205
相关产品推荐
相关产品推荐

