之前有一个业务功能中用到了 Django + Celery 做异步任务,一开始都是各个产品独立创建 Docker 容器,但是后面服务器的负载太高了,所以就转为了各个产品的后端用 Docker 创建容器,而像 MySQL 和 Redis 这种则是直接在服务器上进行操作。

最近出现了一个问题,就是创建 Celery 异步任务的时候一直没有反应,Django 显示接收到了请求,但是 Celery 日志里面没有任务反应。

Django 日志:

记一次 Celery 任务 FAILURE 的 debug 过程({“status“: “FAILURE“, “result“: {“exc_type“: “NotRegistered“……)_Redis


Celery 日志:

记一次 Celery 任务 FAILURE 的 debug 过程({“status“: “FAILURE“, “result“: {“exc_type“: “NotRegistered“……)_异步任务_02

而且这个问题是偶发性的,有的时候会创建,有的时候不会创建。

看了一下 Redis 数据库里的内容,说我任务没有注册。

记一次 Celery 任务 FAILURE 的 debug 过程({“status“: “FAILURE“, “result“: {“exc_type“: “NotRegistered“……)_Redis_03

{"status": "FAILURE", "result": {"exc_type": "NotRegistered", "exc_message": ["StoryBook.tasks.create_story"], "exc_module": "celery.exceptions"}, "traceback": null, "children": [], "date_done": "2024-05-03T07:31:01.086302", "task_id": "99f03720-e9d5-49df-8393-81173463e6ae"}

根据关键词{"status": "FAILURE", "result": {"exc_type": "NotRegistered"搜了一下,找到了 Stack Overflow 上的一个问题:My celery progress always crash in 00:00:00.And I don’t know why,里面提到了一种可能性:当您将某些任务放入队列时,一些神秘的Celery Worker尝试处理它,而不是您期望的过程。

记一次 Celery 任务 FAILURE 的 debug 过程({“status“: “FAILURE“, “result“: {“exc_type“: “NotRegistered“……)_NotRegistered_04

也就是说,我任务创建成功了,但是执行的任务的 Worker 不是我预想的 Worker。所以这就跟背景挂上钩了,因为失误,两个业务共用了一个 Redis 的桶来存 Celery 的任务,所以任务是被另外一个业务的 Celery 执行了,才会说NotRegistered

把两个业务用的 Redis 的桶区分开之后,问题解决。