我正在尝试使用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)
答案 0 :(得分:0)
RabbitMQ是消息代理,而不是文件存储系统。由于假设消息的大小受到一定限制,所以已经进行了一些优化,这些优化将与您的用例相抵触。
要在分布式系统中共享文件,您应该依靠诸如OpenStack Swift或AWS S3之类的对象存储。
您仍然可以使用RabbitMQ通知新文件的存在,但您无需在消息中嵌入新文件,而是在对象存储中提供位置,然后使用者从那里检索文件。
几个参考链接: