请求调试建议:Celery Worker处理中收SIGTERM引发WorkerLostError
问题背景与现象
- 分布式批处理环境基于Amazon EC2自动扩缩容组(ASG)部署数百个Celery Worker,使用RabbitMQ作为消息队列。业务为日间突发模式:队列有消息时扩容Worker,连续10分钟无消息则缩容;作业请求会生成数千条消息,大量使用嵌套chord(chord of chords)结构。
- 近期将系统从Python 3.6+Amazon Linux迁移至Python 3.7+Amazon Linux 2,除基础环境外无其他软件变更(新旧环境均使用Celery 4.4.7、RabbitMQ v3.8.2)。
- 迁移后出现异常:部分Worker在处理过程中触发携带Signal 15的
WorkerLostError,最终导致作业失败。疑似外部进程向Celery Worker发送SIGTERM信号,但日志无法追踪信号来源及触发原因。同一作业(代码完全一致)有时成功有时失败,结果取决于Worker被关闭的时机与位置;迁移前未出现此问题。 - 测试观察:Worker数量越多,问题出现概率越高。50个Worker运行20个测试作业无异常;75个Worker时,20个作业出现1次Worker丢失错误;250个Worker时,20个作业中有10个因该错误失败。已排除EC2实例的内存、CPU、磁盘空间等资源不足问题。
错误堆栈跟踪
Traceback (most recent call last): File "/opt/ev-backend/.venv/lib/python3.7/site-packages/celery/app/builtins.py", line 83, in unlock_chord propagate=True, File "/opt/ev-backend/.venv/lib/python3.7/site-packages/celery/result.py", line 781, in join disable_sync_subtasks=disable_sync_subtasks, File "/opt/ev-backend/.venv/lib/python3.7/site-packages/celery/result.py", line 226, in get self.maybe_throw(callback=callback) File "/opt/ev-backend/.venv/lib/python3.7/site-packages/celery/result.py", line 342, in maybe_throw self.throw(value, self._to_remote_traceback(tb)) File "/opt/ev-backend/.venv/lib/python3.7/site-packages/celery/result.py", line 335, in throw self.on_ready.throw(*args, **kwargs) File "/opt/ev-backend/.venv/lib/python3.7/site-packages/vine/promises.py", line 244, in throw reraise(type(exc), exc, tb) File "/opt/ev-backend/.venv/lib/python3.7/site-packages/vine/five.py", line 195, in reraise raise value celery.exceptions.ChordError: WorkerLostError('Worker exited prematurely: exitcode 15 Job: 0.')
软件依赖列表
alembic 1.4.2 amqp 2.6.1 apsw 3.9.2.post1 attrs 21.4.0 aws-requests-auth 0.4.3 backports.ssl-match-hostname 3.7.0.1 billiard 3.6.4.0 blinker 1.4 boto3 1.17.29 botocore 1.20.112 cachetools 4.2.1 celery 4.4.7 certifi 2021.10.8 chardet 4.0.0 ciso8601 2.1.3 click 8.0.1 coverage 6.3.1 crontab 0.22.9 Cython 0.29.22 decorator 5.1.1 dnspython 2.2.0 elasticsearch 7.11.0 email-validator 1.1.2 Flask 1.1.2 Flask-JsonSchema 0.1.1 Flask-Mail 0.9.1 Flask-Script 2.0.6 Flask-SQLAlchemy 2.4.4 flask-talisman 0.7.0 Flask-WTF 0.14.3 frozendict 2.3.0 future 0.18.2 futures 3.1.1 gitdb 4.0.9 GitPython 3.1.2 healthcheck 1.3.3 idna 2.10 importlib-metadata 4.10.1 iniconfig 1.1.1 itsdangerous 1.1.0 Jinja2 3.0.3 jmespath 0.10.0 join 0.1.1 jsonpath-rw 1.4.0 jsonschema 3.2.0 kombu 4.6.11 Mako 1.1.6 MarkupSafe 2.0.1 numexpr 2.8.1 numpy 1.19.5 overrides 3.1.0 packaging 21.3 pandas 1.1.5 passlib 1.7.4 pip 21.2.4 pluggy 1.0.0 ply 3.11 psutil 5.8.0 psycopg2 2.8.6 py 1.11.0 pyasn1 0.4.8 Pygments 2.8.1 pyparsing 3.0.7 pyrsistent 0.18.1 pytest 7.0.0 pytest-cov 2.11.1 python-dateutil 2.8.1 python-editor 1.0.4 pytz 2020.1 requests 2.25.1 responses 0.13.1 retrying 1.3.3 rsa 4.7.2 s3transfer 0.3.7 scipy 1.5.4 setuptools 60.8.2 simplejson 3.17.2 six 1.16.0 smmap 5.0.0 SQLAlchemy 1.3.23 SQLAlchemy-Utils 0.36.5 supervisor 4.1.0 tables 3.6.1 tomli 2.0.1 typing_extensions 4.0.1 urllib3 1.26.8 vine 1.3.0 Werkzeug 2.0.1 wheel 0.37.1 WTForms 2.3.3 zipp 3.7.0
调试建议
- 追踪SIGTERM信号来源:在Worker实例上启用系统级进程监控,用
strace跟踪Celery Worker进程的信号接收情况,或配置auditd记录发送SIGTERM的进程ID。具体操作:- 对运行中的Celery Worker进程执行
strace -p <pid> -e signal,实时监控信号事件; - 配置audit规则:
auditctl -a exit,always -F arch=b64 -S kill -F a0=15,记录所有发送SIGTERM的操作,后续通过ausearch -i -m kill查看日志。
- 对运行中的Celery Worker进程执行
- 验证ASG缩容逻辑:检查ASG的缩容触发条件是否存在误判,比如队列消息统计是否有延迟导致缩容时机过早。临时延长缩容等待时间(如从10分钟调整到30分钟),观察问题是否缓解;同时监控ASG的缩容事件日志,确认是否在作业执行期间有实例被终止。
- 检查Celery Worker的优雅退出配置:确认Celery Worker的
--soft-time-limit和--time-limit参数设置,以及是否启用了--autoscale。Python3.7与3.6的进程信号处理可能存在差异,尝试调整优雅退出超时时间,比如设置--soft-time-limit 300(5分钟),确保Worker在收到SIGTERM后有足够时间完成当前任务。 - 排查嵌套chord的任务调度问题:开启Celery的详细日志(设置
CELERY_LOG_LEVEL=DEBUG),追踪chord任务的状态流转,确认是否存在任务状态更新不及时导致的误判。同时检查RabbitMQ的队列状态,是否存在未确认的消息或者死信队列堆积。 - 测试Python版本与依赖兼容性:即使依赖版本未变,Python3.7可能与部分依赖存在隐性兼容问题。在Python3.7环境下单独运行单个Worker,执行包含嵌套chord的测试作业,复现问题后逐步排查billiard、kombu等Celery核心依赖的行为差异。
- 监控Worker进程资源使用:监控Worker进程的文件句柄数、线程数等指标。Python3.7的默认资源限制可能与Python3.6不同,可通过
ulimit -n查看文件句柄限制,必要时调整系统配置。 - 检查Supervisor的进程管理配置:若使用Supervisor管理Celery Worker,确认Supervisor的
stopwaitsecs参数设置是否合理,避免Supervisor在Worker未完成任务时强制发送SIGKILL。同时检查Supervisor的日志,是否有异常重启Worker的记录。
内容的提问来源于stack exchange,提问作者cserick18
相关产品推荐
相关产品推荐

