RabbitMQ Pika混乱的邮件正文

时间:2019-01-31 22:14:02

标签: python json rabbitmq pika

我正在尝试使用Python中的RabbitMQ创建一个简单的文件下载和上传服务。我制作了服务器和客户端脚本,并定义了一些对象,这些对象针对请求进行了json序列化和从json反序列化,因此可以将文件uid或其他参数与二进制数据(用base64编码)一起发送。发送小文件时一切正常,但是当我开始发送更大的文件(使用1.4mb文本文件进行测试)时,我开始收到JSONDecode错误。我正在将已发送和已接收的消息转储到文件中,并且看起来已发送的消息是格式正确的json。但是,收到的消息似乎很混乱,例如:

发送:{“ uid”:“ test”,Rhc2Rhc2Rhc2Rhc2Rhc2Rhc2 ==“}

接收到:Rhc2Rhc2 {“ uid”:“ test”,Rhc2Rhc2Rhc2Rhc2 ==“}

显然,混乱的块比这大得多。有人遇到过这个问题吗?

这里有一些代码段,我可以上传完整的代码,但这不是很整洁:

上传请求:

class FileSystemUploadRequest:

def __init__(self, uid, data):
    self.uid = uid
    self.data = data

def encode(self):
    dicc = {"uid": self.uid, "data": base64.b64encode(self.data).decode()}
    return json.dumps(dicc)

@staticmethod
def decode(jsonstr):
    dicc = json.loads(jsonstr)
    uid = dicc["uid"]
    data = base64.b64decode(dicc["data"])
    return FileSystemUploadRequest(uid, data)

客户(发送者):

def put_file_blocking(self, uid, data):

    print(" [x] Llamaron a put_file_blocking")

    corr_id = str(uuid.uuid4())
    request = FileSystemUploadRequest(uid, data)

    f = open("dump", "w")
    f.write(request.encode())
    f.close()

    # Send upload request
    self.channel.basic_publish(exchange='',
                               routing_key=self.queue_upload,
                               properties=pika.BasicProperties(
                                   reply_to=self.callback_queue_name,
                                   correlation_id=corr_id
                               ),
                               body=request.encode())

服务器(接收方):

def upload_request(ch, method, props, body):

f = open("_dump", "w")
f.write(body.decode())
f.close()

# Get Upload Request
request = FileSystemUploadRequest.decode(body)
print(" [x] Received upload request for: " + request.uid)
filename = fs_dir + "/" + request.uid

# Do upload
f = open(filename, "wb")
f.write(request.data)
f.close()

# Create Upload Response
status = Status.OK
response = FileSystemUploadResponse(status)

# Send response
ch.basic_publish(exchange='',
                 routing_key=props.reply_to,
                 properties=pika.BasicProperties(correlation_id=props.correlation_id),
                 body=response.encode())
ch.basic_ack(delivery_tag=method.delivery_tag)

print(" [x] Finished upload request for: " + request.uid)

1 个答案:

答案 0 :(得分:0)

RabbitMQ是消息代理,而不是文件存储系统。由于假设消息的大小受到一定限制,所以已经进行了一些优化,这些优化将与您的用例相抵触。

要在分布式系统中共享文件,您应该依靠诸如OpenStack SwiftAWS S3之类的对象存储。

您仍然可以使用RabbitMQ通知新文件的存在,但您无需在消息中嵌入新文件,而是在对象存储中提供位置,然后使用者从那里检索文件。

几个参考链接:

RabbitMQ best practices

Can RabbitMQ handle big messages?