ECS上Celery任务运行数分钟后意外停止问题排查
数据库闲置连接超时与连接池配置不匹配
数据库(如AWS RDS)通常会设置闲置连接超时时间,若Celery worker持有的数据库连接超过这个时间未被使用,数据库会主动关闭连接。而默认的Django数据库连接池可能不会自动回收这类失效连接,当Celery后续尝试使用该连接时就会抛出错误。
解决:在Django的settings.py中配置CONN_MAX_AGE为小于数据库闲置超时的值(例如300秒),让Django自动回收旧连接;也可以使用django-db-connection-pool等第三方库优化连接管理逻辑。ECS网络层面的连接中断
如果Celery任务采用AWSVPC网络模式,可能出现ENI(弹性网络接口)资源波动、NAT网关连接超时等问题,导致数据库连接被意外切断。另外需确认Celery任务的安全组规则是否持续允许访问数据库端口(如PostgreSQL的5432),避免临时规则失效。
解决:检查ECS任务的网络配置,确保ENI稳定;确认安全组规则中Celery任务所在组到数据库安全组的端口始终开放;若使用NAT网关,可调整其超时设置(默认350秒),或让Celery任务定期发送数据库心跳请求保持连接。Celery Worker未及时重建连接
若未设置Celery worker的--max-tasks-per-child参数,worker进程会长期运行,持有被数据库关闭的失效连接而不自知。当后续任务尝试使用该连接时就会报错。
解决:启动Celery时添加--max-tasks-per-child=50(数值可根据任务量调整),让worker处理一定数量任务后自动重启,重建数据库连接;也可在Celery任务逻辑中手动检查连接有效性,失效时主动重新连接。数据库事务闲置超时
若Celery任务中开启了数据库事务但未及时提交/回滚,数据库的idle_in_transaction_session_timeout参数会触发连接关闭,导致后续操作失败。
解决:检查数据库的idle_in_transaction_session_timeout配置,确保任务中的事务逻辑及时完成提交或回滚;避免在Celery任务中长时间持有未完成的事务。数据库连接配额限制(单用户/IP)
虽然数据库总连接数未达上限,但单个数据库用户或来源IP的连接数可能已被限制,导致Celery无法维持稳定连接。另外若使用RDS Proxy,需确认Celery是否通过Proxy连接,避免直接连接实例时出现配额问题。
解决:检查数据库用户的连接配额,确保Celery使用的账号有足够的连接数;若使用RDS Proxy,统一API和Celery的连接方式,利用Proxy的连接池管理能力。
内容的提问来源于stack exchange,提问作者Affaxerd

