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

Docker Swarm下SQLAlchemy应用空闲15分钟连接超时问题

问题根本原因

你遇到的精确15分钟空闲后数据库连接断开问题,和MariaDB本身默认8小时的连接超时配置无关,根因是Docker Swarm overlay网络默认的TCP空闲连接老化规则:

  • Docker Swarm模式下,跨服务的容器通信默认走VXLAN实现的overlay虚拟网络,宿主机Linux内核的netfilter连接跟踪(conntrack)模块,默认会将连续900秒(即15分钟)没有任何数据包传输的TCP连接标记为失效,直接从连接跟踪表中清除该条目,且不会向连接两端的容器发送RST断开通知,属于静默丢弃。
  • 本地直接运行、普通docker compose up部署时,容器间通信走默认的bridge网络,该网络没有配置15分钟的短空闲超时规则,空闲连接可以一直保持到MariaDB侧8小时超时才会被主动断开,因此不会复现该问题。

报错触发逻辑

SQLAlchemy默认会启动连接池,池内会缓存已经建立好的数据库连接供后续请求复用。当服务连续15分钟没有收到请求时,池内的所有空闲连接都会因为无流量传输,被Swarm overlay网络的conntrack规则判定为失效并清除跟踪记录。
此时新的请求进来,应用从连接池取出这个已经被网络层掐断的旧连接发送查询请求,数据包会被网络层直接丢弃,最终抛出Connection reset by peer、Lost connection to MySQL server during query的错误。

临时规避方案生效的原因

你配置pool_recycle=60*10(10分钟)时,SQLAlchemy会自动销毁连接池内存活时间超过10分钟的连接,下次请求到来时直接新建数据库连接,不会让连接存活到15分钟的网络超时阈值,因此可以绕过网络层的连接丢弃规则。

更稳妥的修复方案

推荐在代码侧创建数据库引擎时,同时配置连接预检测和合理的回收周期,不需要调整基础设施配置即可彻底解决问题:

engine = create_async_engine(
    "mysql+asyncmy://root:pw@mariadbhost/somedb",
    future=True,
    pool_recycle=600, # 10分钟回收,小于网络15分钟超时
    pool_pre_ping=True # 取连接时先做连通性检测,失效连接自动替换
)

注意:不要尝试通过修改MariaDB的wait_timeout参数解决该问题,连接是被中间网络层静默断开的,数据库本身感知不到连接失效,修改数据库侧超时参数完全不生效。

如果要从基础设施侧根治,可以修改所有Swarm节点的Linux内核conntrack参数,将TCP空闲连接超时调整为大于业务连接最大空闲周期的值,但该方案需要修改所有集群节点配置,运维成本较高,一般不推荐。

内容的提问来源于stack exchange,提问作者Mehmet Ates

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:36:18