本文介绍基于MNS,不做消息切片来传递大于64 KB的消息。

背景信息

MNS的队列的消息大小最大限制是64 KB,这个限制基本能够满足在正常情况下消息作为控制流信息交换通道的需求。但是,在某些特殊场景下,消息数据比较大时,就只能采用消息分片的方式。

那么如何能够基于MNS,又不做消息切片,传递大于64 KB的消息呢?解法是有的。

解决方案

  1. 生产者在往MNS发送消息前,如果发现消息体大于64 KB,则先将消息体数据上传到OSS;
  2. 生产者把数据对应的Objcet信息作为消息发送到MNS;
  3. 消费者从MNS队列里读取消息,判断消息内容是否为OSS的Object信息。
    • 如果消息内容是OSS的Object信息,则从OSS下载对应的Object内容,并作为消息体返回给上层程序;
    • 对于大小小于64 KB的消息,仍然直接走MNS。

具体过程如下图所示。

大消息发送流程

程序实现

大消息示例代码提供了上述方案的一个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),默认64 KB;
public void setNeedDeleteMessageObjectOnOSSFlag(boolean flag) // 设置是否需要删除OSS上的消息,默认yes;
			

具体使用示例代码请参见大消息示例代码中的Demo.java。

注意事项

  • 大消息主要消息网络带宽,用该方案发送大消息时,生产者和消费者的网络带宽可能会是瓶颈。
  • 大消息网络传输时间较长,受网络波动影响的概率更大,建议在上层做必要的重试。