Celery任务执行完成却持续处于运行状态的问题排查求助
Celery任务执行完成但显示持续运行的排查与解决
问题概述
Celery任务已执行完成(最后一行打印Leak scan completed),但Worker日志始终显示任务处于运行状态。
相关信息
任务代码
@app.task(ignore_result=True) def leaks_scan(target: str, remove_type: str = "old", **kwargs): url = settings.API_URL + "leaks" skip = 0 limit = 1000 max_limit = 5000 if remove_type == "all": remove_all_data(Leak, target) scan_id = None target_id = None while True: data = get_data(url, target, skip=skip, limit=limit) count = data.get("count") data = data.get("data", []) if not data: if not count: remove_all_data(Leak, target) break break scan_id, target_id = load_leak_data(data) skip += limit if skip > max_limit: break if remove_type == "old" and scan_id and target_id: remove_old_data(Leak, scan_id, target_id) print("Leak scan completed")
环境配置
- Celery版本:5.2.7,Python 3.11.2
- Broker & 结果后端:
redis://localhost:6379/0 - 任务设置:
ignore_result=True
排查与解决步骤
1. 检查任务内子函数的资源与线程问题
任务最后打印了日志,但Worker仍认为任务在运行,大概率是子函数存在未释放的资源或后台线程未终止:
- 检查
get_data:确保网络请求设置合理超时(比如requests.get(..., timeout=10)),避免请求挂起; - 检查
load_leak_data、remove_all_data、remove_old_data:确认数据库连接已归还连接池,没有后台线程(如异步IO线程)未调用join(); - 在任务外层添加
try/except捕获所有异常并打印,避免异常被吞掉导致进程状态异常。
2. 修复ignore_result与结果后端的潜在冲突
任务设置ignore_result=True但全局配置了结果后端,部分Celery版本存在逻辑冲突:
- 尝试移除
ignore_result=True,让Worker正常上报任务状态; - 或在任务末尾添加明确返回值(比如
return "completed"),即使忽略结果,也让函数有明确返回逻辑,避免Worker等待未返回的结果。
3. 解决版本兼容性问题
Celery 5.2.7发布于Python 3.11之前,对3.11的支持存在bug:
- 升级Celery到5.2.10及以上(5.2.x系列首个正式支持Python3.11的版本);
- 或临时降级Python到3.10,验证是否是版本兼容导致的进程管理异常。
4. 切换Worker并发模式测试
默认的prefork池可能存在进程管理bug,尝试用solo模式启动Worker:
celery -A your_app_name worker --pool=solo -l info
如果问题消失,说明是多进程池的资源泄漏或进程僵死问题,可进一步设置--max-tasks-per-child限制单进程处理任务数,避免进程老化。
5. 开启DEBUG日志排查细节
启动Worker时开启DEBUG级别日志,查看任务完成后的详细流程:
celery -A your_app_name worker -l DEBUG
重点关注任务完成后Worker的资源清理、状态上报日志,是否有Redis连接超时、进程退出失败的提示。
内容的提问来源于stack exchange,提问作者OmerFI
相关产品推荐
相关产品推荐

