热门问题:MNS队列消息计数实现难点浅析

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介:
MNS提供GetQueueAttributes接口,用于获取队列的基本属性信息以及队列的消息数状态(可见消息,不可见消息,延迟消息), 其中返回的消息数 并不是精确值,而是只能反映队列中消息数状态的近似值。很多用户可能都会对消息计数不准确而耿耿于怀,小编 今天就跟大家交流交流消息计数的实 现难点,大家请轻拍。
      1. 分布式环境下,强一致性难达到
     MNS是基于阿里飞天分布式平台上的消息服务,具有高并发、高可扩展等优点,别看大家平常只是向一个URL地址收发消息,但
是MNS后端却是多 台Message Server为大家提供服务;各个Message Server会将用户发送的消息数据持久化,同时在内存中维护了实时 的计数信息,并且定期上报计数信息 给Meta管理节点(如图1),Meta管理节点负责管理并持久化Message Server上报的计数数据。用 户调用GetQueueAttributes接口获取的队列属性数据就 是从Meta管理节点中获取到的,所以当您高并发调用消息API时,由于各个 Message Server上报数据的先后关系,您获得的消息计数值就无法做到精确。 特别是当某台Message Server机器发生异常或者failover时, 其精确计数信息可能无法及时上报至Meta管理节点;而Message Server在恢复之后,会将Meta 管理节点中持久化的计数数据load到本地 的内存中, 这样也是造成计数无法做到准确的重要原因。
240_1365541074971606_ef8d74606eae077.jpg
        (图1)


      2. 过期消息
      在MNS中,队列中消息是有过期时间的,如果长时间消息未消费,则消息将变为过期消息,将会被MNS系统回收掉。为了保证消息消费的效率,MNS并不会立刻对过期消息进行回收,只是在保证过期消息不会被用户消费到的前提下,MessageServer后台会有专门的GC模块负责定期回收各个队列的过期消息并 修改 消息计数(如图2)。这就造成了如果存在过期消息,在消息未被回收之前,过期消息还是会体现在消息计数中。
240_1365541074971606_9ea7c9b565091ea.jpg

           (图2)

       以上两点就是MNS目前遇到消息计数不精确的主要 问题 ;同时国外的云计算A公司在其队列服务中提供的也是近似值(如:ApproximateNumberOfMessages)。 应用程序如果强依赖于队列消息计数,并不是分布式高并发环境下最佳选择 ,用户只需要通过长轮询ReceiveMessage接口获取数据即可,如果队列为空,则ReceiveMessage请求将会在MNS端挂起一段时间,期间有任何消息进入队列,挂起的请求都将立刻返回最新的消息;而MNS在队列属性中提供消息计数的初衷主要是提供一个能够大致反映队列堆积情况的,特别当队列计数接入了云监控之后,用户可以轻松通过设置云监控报警来实现队列堆积情况预警;同时在针对消息积压情况进行收费时,我们也是充分考虑到了消息计数可能造成的偏差,目前在MNS的收费用户当中,由于消息积压情况导致收费的并不多,而且也确确实实是堆积了大量消息。但是鉴于计数问题是MNS用户反映最多的问题,所以MNS后续将会推出队列计数最终一致性保障机制。
       大家如果对本文有任何疑问,都可以在帖子中提出,小编会第一时间回复,感谢大家对MNS的支持!我们会不断提升MNS的用户体验,推出更多符合用户使用场景的功能!
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
3月前
|
消息中间件 Java
SpringBoot RabbitMQ死信队列
SpringBoot RabbitMQ死信队列
66 0
|
3月前
|
消息中间件
|
5月前
|
消息中间件 存储 负载均衡
Rabbitmq direct模式保证一个队列只对应一个消费者
Rabbitmq direct模式保证一个队列只对应一个消费者
112 0
|
3月前
|
消息中间件 存储 NoSQL
RabbitMQ的幂等性、优先级队列和惰性队列
【1月更文挑战第12天】用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等
230 1
|
2月前
|
消息中间件 监控 Java
Spring Boot中的RabbitMQ死信队列魔法:从异常到延迟,一网打尽【RabbitMQ实战 一】
Spring Boot中的RabbitMQ死信队列魔法:从异常到延迟,一网打尽【RabbitMQ实战 一】
63 0
|
1月前
|
消息中间件 前端开发 算法
【十七】RabbitMQ基础篇(延迟队列和死信队列实战)
【十七】RabbitMQ基础篇(延迟队列和死信队列实战)
42 1
|
2月前
|
消息中间件 监控 数据挖掘
兔子的后院奇遇:深入了解RabbitMQ中的死信队列【RabbitMQ 四】
兔子的后院奇遇:深入了解RabbitMQ中的死信队列【RabbitMQ 四】
48 0
|
2月前
|
消息中间件 Docker 容器
docker构建rabbitmq并配置延迟队列插件
docker构建rabbitmq并配置延迟队列插件
35 0
|
2月前
|
消息中间件
rabbitmq动态创建队列
rabbitmq动态创建队列
36 0
|
3月前
|
消息中间件 存储 Java
RabbitMQ之延迟队列(手把手教你学习延迟队列)
【1月更文挑战第12天】延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列的。
343 1