问题背景
阿里云消息服务mns的队列的消息大小最大限制是64k,这个限制基本能够满足在正常情况下消息作为控制流信息交换通道的需求。但是,在某些特殊场景下,消息数据比较大时,就只能采用消息分片的方式。
那么如何能够基于mns,又不做消息切片,传递大于64k的消息呢?解法是有的。
解决方案
1.生产者在往mns 发送消息前,如果发现消息体大于64k,则先将消息体数据上传到oss上;
2.然后,生产者把数据对应的objcet信息作为消息发送到mns上;3.消费者从mns队列里读取消息,判断消息内容是否为oss的object信息;
4.如果消息内容是oss的object信息,则从oss下载对应的object内容,并作为消息体返回给上层程序;
5.对于大小小于64k的消息,仍然直接走mns。
具体过程如下图所示:
程序实现
附件(
bigmessagequeue.rar (2976 k) )提供了上述方案的一个java语言版实现。主要功能都封装成类:bigmessagesizequeue
bigmessagesizequeue提供的public方法如下:
public bigmessagesizequeue(cloudqueue cq, ossclient ossclient, string ossbucketname)
//构造函数,cq为普通的mnsqueue对象,ossclient和ossbucketname包含了大消息中转的oss region和bucket
public message putmessage(message message) // 发送消息
public message popmessage(int waitseconds) // 接收消息
public void deletemessage(string receipthandle) //删除消息
public void setbigmessagesize(long bigmessagesize) //设置大消息的阀值(大于这个值的消息会走oss),默认64k;
public void setneeddeletemessageobjectonossflag(boolean flag) // 设置是否需要删除oss上的消息,默认yes;
具体使用demo 请参考附件中demo.java中的代码。
注意事项
1.大消息主要消息网络带宽,用该方案发送大size消息时,生产者和消费者的网络带宽可能会是瓶颈。
2.大消息网络传输时间较长,受网络波动影响的概率更大,建议在上层做必要的重试。