如何解决AWS SSM端口转发会话超时问题?
SSM端口转发会话超时的诊断与解决方法
可能的超时原因
- SSM会话的空闲判定逻辑:SSM的空闲超时不是看应用脚本是否在运行,而是看端口转发通道上是否有持续的数据包传输。哪怕你的Python脚本在本地处理数据,只要MySQL连接长时间无交互(比如批量插入间隙、本地数据处理阶段),SSM就会判定通道空闲触发超时。
- SSM Agent会话生命周期限制:除了空闲超时,SSM会话本身有默认24小时的最大生命周期限制,不过数小时就断的情况更偏向于空闲判定问题,但仍需排查。
- 网络层隐性中断:本地网络波动、AWS SSM服务端临时链路问题,或者中间NAT/防火墙主动断开长时间连接(哪怕有少量数据包)也可能导致超时。
诊断步骤
- 启用SSM会话详细日志
- 运行端口转发命令时添加
--debug参数,查看超时前的数据包传输记录,验证通道是否真的处于空闲状态:aws ssm start-session --target <EC2实例ID> --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<RDS端点>"], "portNumber":["3306"], "localPort":["3306"]}' --debug
- 运行端口转发命令时添加
- 监控MySQL连接状态
- 在RDS控制台查看
Connections和Bytes Transferred指标,确认超时前是否有数据传输中断。 - 执行MySQL命令
SHOW PROCESSLIST;,观察脚本对应的连接是否长时间处于Sleep状态,时长是否超过SSM空闲超时设置。
- 在RDS控制台查看
- 测试纯网络层面的持续连通性
- 在端口转发通道上持续发送小数据包,同时运行脚本,看是否还会超时:
while true; do echo "keep-alive" | nc localhost 3306; sleep 5; done - 如果不再超时,说明确实是通道空闲导致的问题。
- 在端口转发通道上持续发送小数据包,同时运行脚本,看是否还会超时:
解决方法
- 优化应用层连接交互
- 调整Python脚本的插入逻辑,避免长时间本地数据处理后才批量提交。比如分批次处理并提交,每批次之间执行
SELECT 1;这类轻量查询保持连接活跃。 - 调整MySQL的
wait_timeout和interactive_timeout参数,避免数据库连接先于SSM会话断开(辅助优化)。
- 调整Python脚本的插入逻辑,避免长时间本地数据处理后才批量提交。比如分批次处理并提交,每批次之间执行
- 强制SSM通道心跳包
- 用
autossh封装SSM SSH会话做端口转发,利用SSH心跳包保持通道活跃:autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 3306:<RDS端点>:3306 ec2-user@<EC2实例ID> -i <密钥文件> -o ProxyCommand="aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
- 用
- 配置持久化SSM会话
- 自定义SSM文档,将
idleTimeout设为最大值60分钟,同时更新EC2实例上的SSM Agent到最新版本(旧版本可能存在空闲判定bug):sudo yum update amazon-ssm-agent -y # Amazon Linux系统 sudo systemctl restart amazon-ssm-agent
- 自定义SSM文档,将
- 绕过SSM端口转发限制
- 如果允许,将Python脚本部署到VPC内的EC2实例上直接连接RDS,彻底避免SSM会话的超时限制。
内容的提问来源于stack exchange,提问作者Will Haley
相关产品推荐
相关产品推荐

