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

本地通过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 33336
    
    若输出包含open则通路正常,否则排查以下两点:
    • 调整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端口的入站请求,可临时关闭防火墙测试,或添加允许规则。

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
    
  • 执行连接命令测试:
    mysql -h host.docker.internal -P 33336 -u <user> -p <db_name>
    
    若连接失败,说明容器到宿主机隧道的通路存在问题;若连接成功,则需排查Lambda代码的配置或连接池逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:42:49