使用Pika 0.9.5将大消息发送到RabbitMQ:Rabbit会自动删除消息

使用Pika 0.9.5将大消息发送到RabbitMQ:Rabbit会自动删除消息,rabbitmq,celery,pika,Rabbitmq,Celery,Pika,我有一堆芹菜任务,它们将结果发送到RabbitMQ消息队列。发布的结果可能会变得相当大(高达几兆)。关于在RabbitMQ消息中放入大量数据是否是一个好主意,人们的看法不一,但我在其他情况下见过这种方法,只要内存处于控制之下,它似乎就可以工作 然而,对于我当前的一组任务,rabbit似乎只是删除了看起来太大的消息。我将其简化为一个相当简单的测试用例: #!/usr/bin/env python import string import random import pika import os q

我有一堆芹菜任务,它们将结果发送到RabbitMQ消息队列。发布的结果可能会变得相当大(高达几兆)。关于在RabbitMQ消息中放入大量数据是否是一个好主意,人们的看法不一,但我在其他情况下见过这种方法,只要内存处于控制之下,它似乎就可以工作

然而,对于我当前的一组任务,rabbit似乎只是删除了看起来太大的消息。我将其简化为一个相当简单的测试用例:

#!/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
将robins循环到每个节点。客户端在Ubuntu 12.04上使用Pika 0.9.5,RabbitMQ集群在Erlang R14B04上运行RabbitMQ 2.8.7

执行此脚本将打印print语句并在不引发任何异常的情况下退出。消息从未出现在RabbitMQ中

N
更改为
10000
可使其按预期工作


为什么?

我想您对RabbitMq中的tcp背压机制有问题。你可以读到。 我认为有两种方法可以解决这个问题:

  • 添加tcp回调并重新连接来自rabbit的每个tcp调用
  • 在发送给兔子之前使用压缩消息,这将使推送到兔子更容易

  • 这就是我发送和接收数据包的方法。它比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)
    

    rabbitmq日志说明了什么吗?如果您将芹菜改为使用librabbitmq客户端,是否有帮助?(您只需执行
    pip安装librabbitmq
    ,amqp://alias即可使用它)
    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)