我想将 RabbitMQ 与 Django 一起使用来进行消息队列。目前,我在每个 Django 应用程序服务器上都有一个新的 RabbitMQ 和芹菜实例。我想知道这是最好的方法吗?或者我应该有一个 RabbitMQ 集群来排队消息,并有多个芹菜来执行这些任务?
如果你对 Web 应用进行负载均衡,并且你打算在每个主机上运行多个 celery worker,那么你肯定希望所有工作线程使用相同的 rabbitmq 群集。我喜欢将我的 rabbitmq 集群分布在我运行工作线程的节点上,并打开了队列持久性功能。但是您可以选择拥有单独的兔子集群(取决于您的预算)。
如果您运行多个单独的应用程序,那么我会只为该应用程序在本地运行兔子。
--编辑--
在评论中,您提到您的应用程序是负载平衡的,并且您正在尝试对兔子进行集群,并且多个工作线程执行同一任务时遇到问题。
我想到了几件事,如果您可以发布您的 celery.py/celeryconfig.py 和示例代码,说明如何将任务插入队列,那就太好了。
在这一点上,我可以就集群提出建议,因为这非常简单:
- 选择您的主群集节点(即主机名 rabbit1)
- 在辅助群集节点上删除/var/lib/rabbitmq/* 的内容(不要删除文件夹本身!
- 在辅助群集节点上,从主节点复制 .erlang.cookie(它应该是在您第一次启动 rabbitmq 时创建的,通常可以在/var/lib/rabbitmq/.erlang.cookie 下找到它);此文件必须在两个节点上保存完全相同的内容,并且还必须由 rabbitmq:rabbitmq 拥有,并切断组和其他内容。
- 确保您的/etc/hosts 在两个节点上都提到了两个节点
- 启动两个节点
- 在辅助节点上运行以下命令(作为 rabbitmq 用户,这很重要,因为 .erlang.cookie 是按用户创建的,并且很可能您的 rabbitmq 进程以 rabbitmq 用户身份运行):
(以下命令在 rabbit2 上运行)
rabbitmqctl stop_app
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app
rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
注意 - 最后一个命令是使队列跨节点持久化,因此当一个节点死亡时,您的集群将继续工作而不会丢失任何任务。
您可以使用以下命令检查集群是否正常工作:
rabbitmqctl cluster_status
我建议您是否可以停止所有工作人员并将一个任务插入队列,然后运行以下命令以查看队列中是否只有一个任务:
rabbitmqctl list_queues -p your_vhost_name
队列中应只有一个任务。
然后,您可以检查您正在使用的交易所是什么。从您的评论中,我猜您可能正在使用扇出交换。我对交易所不太深入,但您可以通过运行以下命令来检查您的交易所:
rabbitmqctl list_exchanges -p your_vhost_name
或分析以下输出:
rabbitmqctl report