我有一堆芹菜任务,他们将结果发布到RabbitMQ消息队列中。发布的结果可能会变得非常大(高达几兆)。对于是否在RabbitMQ消息中放入大量数据是个好主意,意见不一,但我在其他情况下看到过这项工作,只要内存得到控制,它似乎就有用了。
然而,对于我目前的一系列任务,兔子似乎只是放弃了似乎太大的消息。我把它简化为一个相当简单的测试用例:
#!/usr/bin/env python
import string
import random
import pika
import os
qname='examplequeue'
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='mq.example.com'))
channel = connection.channel()
channel.queue_declare(queue=qname,durable=True)
N=100000
body = ''.join(random.choice(string.ascii_uppercase) for x in range(N))
promise = channel.basic_publish(exchange='', routing_key=qname, body=body, mandatory=0, immediate=0, properties=pika.BasicProperties(content_type="text/plain",delivery_mode=2))
print " [x] Sent 'Hello World!'"
connection.close()
我有一个3节点RabbitMQ群集,每个节点都有mq.example.com
个循环。客户端在Ubuntu 12.04上使用Pika 0.9.5,而RabbitMQ集群在Erlang R14B04上运行RabbitMQ 2.8.7。
执行此脚本会打印print语句并退出而不会引发任何异常。该消息永远不会出现在RabbitMQ中。
将N
更改为10000
会使其按预期工作。
为什么?
答案 0 :(得分:2)
我想你在RabbitMq中遇到了tcp-backpressure mechanizm的问题。你可以阅读http://www.rabbitmq.com/memory.html。 我看到两种解决这个问题的方法:
def compress(s): return binascii.hexlify(zlib.compress(s)) def decompress(s): return zlib.decompress(binascii.unhexlify(s))
答案 1 :(得分:0)
这就是我发送和接收数据包的方式。它比hexlify效率更高,因为base64可能使用一个字节,而hexlify需要两个字节来表示一个字符。
import zlib
import base64
def hexpress(send: str):
print(f"send: {send}")
bsend = send.encode()
print(f"byte-encoded send: {bsend}")
zbsend = zlib.compress(bsend)
print(f"zipped-byte-encoded-send: {zbsend}")
hzbsend = base64.b64encode(zbsend)
print(f"hex-zip-byte-encoded-send: {hzbsend}")
shzbsend = hzbsend.decode()
print(f"string-hex-zip-byte-encoded-send: {shzbsend}")
return shzbsend
def hextract(recv: str):
print(f"string-hex-zip-byte-encoded-recv: {recv}")
zbrecv = base64.b64decode(recv)
print(f"zipped-byte-encoded-recv: {zbrecv}")
brecv = zlib.decompress(zbrecv)
print(f"byte-encoded-recv: {brecv}")
recv = brecv.decode()
print(f"recv: {recv}")
return recv
print("sending ...\n")
send = "hello this is dog"
packet = hexpress(send)
print("\nover the wire -------->>>>>\n")
print("receiving...\n")
recv = hextract(packet)