Django、RabbitMQ 和Celery - 为什么在我更新开发中的 Django 代码后,Celery 会运行旧版本的任务?

2022-01-11 00:00:00 python django celery django-celery rabbitmq

问题描述

所以我有一个 Django 应用程序,它偶尔会向 Celery 发送一个任务以进行异步执行.我发现当我在开发中处理我的代码时,Django 开发服务器知道如何自动检测代码何时发生更改,然后重新启动服务器,以便我可以看到我的更改.但是,我的应用程序的 RabbitMQ/Celery 部分并没有注意到开发中的这些变化.如果我更改稍后将在 Celery 任务中运行的代码,Celery 仍将继续运行旧版本的代码.我能让它接受变化的唯一方法是:

So I have a Django app that occasionally sends a task to Celery for asynchronous execution. I've found that as I work on my code in development, the Django development server knows how to automatically detect when code has changed and then restart the server so I can see my changes. However, the RabbitMQ/Celery section of my app doesn't pick up on these sorts of changes in development. If I change code that will later be run in a Celery task, Celery will still keep running the old version of the code. The only way I can get it to pick up on the change is to:

  1. 停止 Celery 工人
  2. 停止 RabbitMQ
  3. 重置 RabbitMQ
  4. 启动 RabbitMQ
  5. 将用户添加到我的 Django 应用配置使用的 RabbitMQ
  6. 为此用户设置适当的权限
  7. 重启 Celery worker

然而,这似乎是一种比我应该采取的更为激进的方法.我可以使用更轻量级的方法吗?

This seems like a far more drastic approach than I should have to take, however. Is there a more lightweight approach I can use?


解决方案

我发现当我在开发中处理我的代码时,Django开发服务器知道如何自动检测代码何时更改然后重新启动服务器,以便我可以看到我的更改.然而,我的应用程序的 RabbitMQ/Celery 部分不支持这些类型发展变化.

I've found that as I work on my code in development, the Django development server knows how to automatically detect when code has changed and then restart the server so I can see my changes. However, the RabbitMQ/Celery section of my app doesn't pick up on these sorts of changes in development.

您在此处描述的内容完全正确且符合预期.请记住,Python 将使用 模块缓存,因此您需要重新启动 Python 解释器,然后才能使用新代码.

What you've described here is exactly correct and expected. Keep in mind that Python will use a module cache, so you WILL need to restart the Python interpreter before you can use the new code.

问题是为什么 Celery 不选择新版本",但这是大多数库的工作方式.然而,Django 开发服务器是一个例外.它有特殊的代码,可以帮助它根据需要自动重新加载 Python 代码.它基本上是重启web服务器而不需要重启web服务器.

The question is "Why doesn't Celery pick up the new version", but this is how most libraries will work. The Django development server, however, is an exception. It has special code that helps it automatically reload Python code as necessary. It basically restarts the web server without you needing to restart the web server.

请注意,当您在生产环境中运行 Django 时,您可能需要重新启动/重新加载服务器(因为您不会在生产环境中使用开发服务器,而且大多数生产服务器不会尝试承担实现检测文件更改和自动重新加载服务器的问题功能.

Note that when you run Django in production, you probably WILL have to restart/reload your server (since you won't be using the development server in production, and most production servers don't try to take on the hassle of implementing a problematic feature of detecting file changes and auto-reloading the server).

最后,您不需要重新启动 RabbitMQ.您只需要重新启动 Celery worker 即可使用新版本的 Python 代码.但是,如果新版本的代码正在更改消息中的数据,您可能必须清除队列.例如,Celery 工作人员可能正在接收版本 1 的消息,而它期望接收版本 2.

Finally, you shouldn't need to restart RabbitMQ. You should only have to restart the Celery worker to use the new version of the Python code. You might have to clear the queue if the new version of the code is changing the data in the message, however. For example, the Celery worker might be receiving version 1 of the message when it is expecting to receive version 2.

相关文章