如果您对 Web 应用程序进行负载平衡,并且您的意图是在每个主机上运行多个 celery worker,那么您肯定希望所有 worker 使用同一个 rabbitmq 集群。我喜欢将我的 rabbitmq 集群分布在我运行 worker 的节点上,并打开队列持久性功能。但是您可以选择使用单独的兔子集群(取决于您的预算)。
如果您运行多个单独的应用程序,那么我会为该应用程序在本地运行 rabbit。
-- 编辑--
在评论中,您提到您的应用是负载平衡的,并且您正在尝试集群 rabbit 并且遇到多个工作人员执行同一任务的问题。
我想到了一些事情,如果你能发布你的 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