热门问题: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到本地 的内存中, 这样也是造成计数无法做到准确的重要原因。

        (图1)


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

           (图2)

       以上两点就是MNS目前遇到消息计数不精确的主要 问题 ;同时国外的云计算A公司在其队列服务中提供的也是近似值(如:ApproximateNumberOfMessages)。 应用程序如果强依赖于队列消息计数,并不是分布式高并发环境下最佳选择 ,用户只需要通过长轮询ReceiveMessage接口获取数据即可,如果队列为空,则ReceiveMessage请求将会在MNS端挂起一段时间,期间有任何消息进入队列,挂起的请求都将立刻返回最新的消息;而MNS在队列属性中提供消息计数的初衷主要是提供一个能够大致反映队列堆积情况的,特别当队列计数接入了云监控之后,用户可以轻松通过设置云监控报警来实现队列堆积情况预警;同时在针对消息积压情况进行收费时,我们也是充分考虑到了消息计数可能造成的偏差,目前在MNS的收费用户当中,由于消息积压情况导致收费的并不多,而且也确确实实是堆积了大量消息。但是鉴于计数问题是MNS用户反映最多的问题,所以MNS后续将会推出队列计数最终一致性保障机制。
       大家如果对本文有任何疑问,都可以在帖子中提出,小编会第一时间回复,感谢大家对MNS的支持!我们会不断提升MNS的用户体验,推出更多符合用户使用场景的功能!
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
6月前
|
消息中间件 Java Spring
SpringBoot实现RabbitMQ的简单队列(SpringAMQP 实现简单队列)
SpringBoot实现RabbitMQ的简单队列(SpringAMQP 实现简单队列)
54 1
|
1月前
|
消息中间件 存储 监控
RabbitMQ 队列之战:Classic 和 Quorum 的性能洞察
RabbitMQ 是一个功能强大的消息代理,用于分布式应用程序间的通信。它通过队列临时存储消息,支持异步通信和解耦。经典队列适合高吞吐量和低延迟场景,而仲裁队列则提供高可用性和容错能力,适用于关键任务系统。选择哪种队列取决于性能、持久性和容错性的需求。
121 6
|
2月前
|
消息中间件 JSON Java
|
2月前
|
消息中间件
rabbitmq,&队列
rabbitmq,&队列
|
2月前
|
消息中间件 JSON Java
玩转RabbitMQ声明队列交换机、消息转换器
玩转RabbitMQ声明队列交换机、消息转换器
84 0
|
3月前
|
消息中间件 存储 NoSQL
MQ的顺序性保证:顺序队列、消息编号、分布式锁,一文全掌握!
【8月更文挑战第24天】消息队列(MQ)是分布式系统的关键组件,用于实现系统解耦、提升可扩展性和可用性。保证消息顺序性是其重要挑战之一。本文介绍三种常用策略:顺序队列、消息编号与分布式锁,通过示例展示如何确保消息按需排序。这些方法各有优势,可根据实际场景灵活选用。提供的Java示例有助于加深理解与实践应用。
86 2
|
4月前
|
消息中间件 RocketMQ
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
MetaQ/RocketMQ 原理问题之当消费集群规模较大时,处理分配不到队列的Consumer的问题如何解决
|
4月前
|
消息中间件 Java Kafka
说说RabbitMQ延迟队列实现原理?
说说RabbitMQ延迟队列实现原理?
69 0
说说RabbitMQ延迟队列实现原理?
|
4月前
|
消息中间件 NoSQL 关系型数据库
【RocketMQ系列十三】RocketMQ的集群核心概念之消费重试&死信队列&幂等消息的出现以及处理
【RocketMQ系列十三】RocketMQ的集群核心概念之消费重试&死信队列&幂等消息的出现以及处理
129 1
|
5月前
|
消息中间件 存储 监控
RabbitMQ 死信队列
RabbitMQ的死信队列(DLQ)是存储无法正常消费消息的特殊队列,常见于消息被拒绝、过期或队列满时。DLQ用于异常处理、任务调度和监控,通过绑定到普通队列自动路由死信消息。通过监听死信队列,可以对异常消息进行补偿和进一步处理,提升系统稳定性和可维护性。
87 1