Retool经SSH隧道连私有RDS MySQL 会话中途停发查询排查
在AWS私有子网中部署RDS MySQL实例,公网子网内部署堡垒机(bastion host)。Retool使用平台提供的SSH密钥及指定IP列表配置MySQL连接,初始连接测试可正常通过,每个会话开启初期可正常执行大量数据库读写操作,数据库侧可观测到对应访问活动。
会话运行过程中随机出现Retool无法连接RDS实例的问题:Retool上的SQL查询运行耗时异常增长、完全卡死无返回,此时在MySQL实例执行SHOW PROCESSLIST,通常观测不到任何查询请求到达数据库。
- 整套AWS基础设施通过Terraform编排生成,采用最新版AWS VPC模块,未部署NAT网关
- 堡垒机由弹性伸缩组(autoscaling组)托管,实例规格为t3.nano,监控数据未观测到CPU或网络带宽占用过高情况,本地通过SSH连接堡垒机测试正常,更换更大规格实例后故障仍复现
- 在堡垒机上执行
nslookup、dig可正常解析RDS实例域名,该套网络架构此前有成功落地经验 - RDS实例部署在私有子网,通过AWS/OpenVPN VPN连接可稳定访问,Retool故障发生时,本地通过VPN访问RDS无异常
- RDS为默认原生配置,未做自定义参数调整,事务隔离级别为默认值,采用私有主机名做DNS路由,RDS的安全组已放通堡垒机的访问权限
1. 优先排查SSH隧道空闲静默断连问题
这类架构下90%的随机连接卡死都根源于此:当SSH隧道一段时间没有流量传输,会被路径上的安全组、网络ACL、系统防火墙等设备判定为空闲连接直接丢弃,且丢弃时不会向连接两端(Retool、RDS)发送断开通知。此时Retool侧会认为旧连接仍然有效,发送查询请求时不会主动重建隧道,请求直接卡在网络层无法到达RDS,因此执行SHOW PROCESSLIST看不到任何新请求。
对应排查与修复操作:
- 调整堡垒机SSH服务保活配置:编辑
/etc/ssh/sshd_config,添加或修改以下参数:
ClientAliveInterval 30 ClientAliveCountMax 3 TCPKeepAlive yes
修改完成后重启sshd服务生效。
- 调整堡垒机操作系统TCP保活参数:执行以下命令临时生效,同时将参数写入
/etc/sysctl.conf实现重启持久化:
sysctl -w net.ipv4.tcp_keepalive_time=60 sysctl -w net.ipv4.tcp_keepalive_intvl=10 sysctl -w net.ipv4.tcp_keepalive_probes=6
- 确认AWS侧网络超时规则:公网子网关联的安全组默认有状态连接空闲超时为350秒,不要配置更短的超时阈值;Retool侧的MySQL连接配置中,将空闲连接回收时间设置为小于300秒,强制定期回收僵死连接,避免复用无效隧道。
2. 排查堡垒机弹性伸缩逻辑导致的隧道意外中断
由于堡垒机由autoscaling组托管,若伸缩组触发实例替换(比如跨可用区均衡、健康检查误判、实例到期回收等),旧实例上已经建立的所有SSH隧道会直接中断,若Retool侧未及时感知隧道状态,就会出现请求卡死。
对应排查操作:
- 故障发生第一时间登录当前运行的堡垒机,执行
ss -antp | grep :22查看现存SSH连接,确认Retool出口IP对应的隧道连接是否存在。 - 查看堡垒机系统日志
/var/log/auth.log、/var/log/messages,核对故障时间点是否有SSH连接断开、实例重启、公网IP变动的记录。 - 若确认是伸缩组替换实例导致,可调整伸缩组健康检查宽限期、关闭不必要的实例回收策略,或为堡垒机实例绑定固定EIP,避免实例意外替换。
3. 排查MTU不匹配导致的大包丢包
AWS VPC默认网络MTU为1500,SSH隧道封装数据包会额外占用包头空间,若封装后的数据包大小超过路径MTU,且ICMP不可达报文被安全组拦截,就会出现小请求正常、大查询(返回结果集大、写入数据量大的请求)触发丢包、连接卡死的现象,和“会话初期可正常执行操作、运行一段时间随机卡死”的特征吻合。
对应排查与修复操作:
- 在堡垒机上执行
ping -M do -s 1472 <RDS实例私有IP>,测试不分片的最大数据包是否能正常连通,若出现丢包则确认存在MTU问题。 - 执行以下iptables规则配置MSS钳制,适配隧道封装后的包大小:
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
配置后持续观测故障是否复现。
4. 排查RDS连接数耗尽问题
虽然RDS为默认配置,但如果Retool侧存在连接泄漏,会逐渐占满RDS的最大连接数,新的连接请求会被直接丢弃。故障发生时可以查看RDS监控中的CurrentConnections指标,对比当前实例规格对应的最大连接数阈值,如果指标接近阈值,需要在Retool侧配置连接池上限、设置空闲连接自动回收规则,避免无效连接长期占用RDS连接配额。
内容的提问来源于stack exchange,提问作者wonky89

