[英]Python: Kombu+RabbitMQ Deadlock - queues are either blocked or blocking
我有一个RabbitMQ服务器 ,作为我的一个系统的队列中心。 在过去一周左右,它的制作人每隔几个小时就会完全停止。
在cantSleepNow的回答之后 ,我将分配给RabbitMQ的内存增加到90% 。 服务器有16GB的内存,消息数量不是很高(每天数百万),所以这似乎不是问题。
从命令行:
sudo rabbitmqctl set_vm_memory_high_watermark 0.9
并使用/etc/rabbitmq/rabbitmq.config
:
[
{rabbit,
[
{loopback_users, []},
{vm_memory_high_watermark, 0.9}
]
}
].
我为所有消费者和生产者使用Python。
生产者是提供呼叫的API服务器。 每当呼叫到达时,都会打开一个连接,发送一条消息并关闭连接。
from kombu import Connection
def send_message_to_queue(host, port, queue_name, message):
"""Sends a single message to the queue."""
with Connection('amqp://guest:guest@%s:%s//' % (host, port)) as conn:
simple_queue = conn.SimpleQueue(name=queue_name, no_ack=True)
simple_queue.put(message)
simple_queue.close()
消费者彼此略有不同,但通常使用以下模式 - 打开连接,并等待消息到达。 连接可以长时间保持打开状态(比如几天)。
with Connection('amqp://whatever:whatever@whatever:whatever//') as conn:
while True:
queue = conn.SimpleQueue(queue_name)
message = queue.get(block=True)
message.ack()
直到大约一周前,这种设计没有引起任何问题。
Web控制台显示,消费者在127.0.0.1
和172.31.38.50
阻止消费者从172.31.38.50
, 172.31.39.120
, 172.31.41.38
和172.31.41.38
。
为了安全起见,我检查了服务器负载。 正如预期的那样,负载平均值和CPU利用率指标很低。
为什么兔子MQ每次都这么僵局?
我写这个作为答案,部分是因为它可能有所帮助,部分原因是因为它太大而无法作为评论。
首先,我很抱歉错过了这条message = queue.get(block=True)
。 免责声明 - 我不熟悉python或PIKA API。
AMQP的basic.get
实际上是同步的 ,你设置的是block=true
。 正如我所说,不知道这对PIKA意味着什么,但结合不断汇集队列,听起来效率不高。 因此,出于某种原因,由于消费者阻止了队列访问,发布者可能会被拒绝连接。 它实际上非常适合你暂时解决问题的方法, Stopping the consumers releases the lock for a few minutes, but then blocking returns.
我建议尝试使用AMQP的basic.consume
而不是basic.get
。 我不知道获得的动机是什么,但在大多数情况下(无论如何我的体验)你应该选择消费。 只是引用上述链接
此方法使用专为特定类型的应用程序设计的同步对话框直接访问队列中的消息,其中同步功能比性能更重要。
在RabbitMQ文档中,它表示当代理资源不足时连接被阻止,但是当你写入时,负载非常低。 为了安全起见,您可以检查内存消耗和可用磁盘空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.