浅析什么是顺序消息?

简介: 在日常开发中,或多或少的都遇到过顺序消息的使用场景,那么为什么要使用顺序消息呢?如果不使用顺序消息会有什么问题吗?市面上的消息中间件又是如何实现的呢?

前言

image.png
相信大家在日常开发中,或多或少的都遇到过顺序消息的使用场景,那么为什么要使用顺序消息呢?如果不使用顺序消息会有什么问题吗?市面上的消息中间件又是如何实现的呢?

为什么要使用顺序消息?

以大家在电商平台下单退款举例,可以想想如果要下一笔订单,我们需要经过一个什么样的状态流转?如下图所示,在大部分在线的交易的电商平台中,如下场景是必不可少的,但是你回顾一下这个流程,假如顺序发生了调换,又会产生什么样的效果呢?
image.png
仅仅只看这个流程的话,如果在创建完订单,在用户还未支付的情况下,用户还能发起退款,对于平台来说就产生了资损。(注:此处只是单拿现实场景举例,实例支持在线交易的平台,绝不是一两句就能囊括的)
image.png
所以说:假如一个订单支付流程需要这几条消息分别处理,那么消费时就必须要按照设定的顺序消费才有完整的业务含义。但是需要注意的是,在多个订单之间是可以并行消费的,也是A订单是不依赖其他订单的顺序的。(但是在某些复杂的系统中也会出现,例如旅游系统的中的套票或者某些酒店系统中的父子订单等概念。)
image.png

消息的有序性

通过上文,我们大致了解到为什么要顺序消息。但是从此上图3来看的话,我们把这条链路当做一个消息队列,似乎这个队列的消息都是有序的,也就是全局有序。但是假如我们订单量很多的情况,系统中只有这一个消息队列,为了保证消息投递有序,只能有一个生产者,这严重了影响了系统性能跟用户的体验,总不能下个订单,在后台刷了2个小时,订单还没有吧?
image.png
那么针对此上问题,为了提高系统的生产消费性能,我们是不是可以考虑到可以使用多个队列并行消费呢?我们是不是只需要保证每个订单的创建支付流程是有序的,也就是局部有序就可以了。如下图
image.png
但上图也会衍生出一个问题,如何保证保证一组消息流程,能在同一个队列中呢?其实解决这个问题也很简单,我们只需要在生产者投递消息的时候,根据某种自定义的策略(例如hash取模等等),将每个订单统一按照此策略投递固定的其中一个队列即可,如下图所示。
image.png
像如上这种方式,同一个订单的消息是一定有序的,但是不同的订单是无序的,也就是我们上文所说的局部有序。但是这种情况下,会不会有问题呢?消息一定能有序吗,假如队列因为某种原因减少一个,那这时候还能保证顺序吗?如下图:
image.png

很明显如果队列数在运行时发送变更,那么可能会带来后果就是部分消息是无序的。

消费者有序消费

在上文中没有提到的一点就是,如果多个消费者,在消费消息的时候,或者单个消费者多线程并行消费的时候,如果不加以处理,可能也会造成消息乱序消费的结果。而大部分普遍的做法就是通过分布式锁或者JDK等提供的本地锁来保证同时只有一条线程去消费一个队列上的数据。

小结

通过上文,我们简单的了解到什么是顺序消息,而同样顺序消息存在的几个问题点相信你也能从文中看出。因为消费者实现有序消息需要加锁,所以性能肯定有损耗。再者就是为了保证顺序的消息的有序性,如果前一个消息因为某种原因导致失败,那么后续的消息肯定是无法执行的,因为我们要不停的重试这条失败的消息来保证有序性,但是这种无限的重试,也会导致其他的流程的暂停,所以通常的做法就是指定重试的次数,另外做好这种异常的捕获与处理,防止未知的情况发生。

目录
相关文章
|
3月前
|
消息中间件 存储 负载均衡
RocketMQ 消息的顺序和重复
这篇文章探讨了RocketMQ中消息顺序和重复的问题,解释了为什么RocketMQ不保证消息顺序和不重复,并提供了解决这些问题的策略,包括消费端幂等性处理和使用日志表记录已处理消息ID,同时介绍了RocketMQ的事务消息、Producer和Consumer的最佳实践,以及其他配置和RocketMQ的基本概念。
46 0
RocketMQ 消息的顺序和重复
|
4月前
|
消息中间件 SQL RocketMQ
【RocketMQ系列五】消息示例-顺序消息&延迟消息&广播消息的实现
【RocketMQ系列五】消息示例-顺序消息&延迟消息&广播消息的实现
78 1
|
消息中间件 NoSQL Redis
消息重复消费的问题
消息重复消费的问题
|
6月前
|
消息中间件 存储 Kafka
几种 MQ 顺序消息的实现方式
几种 MQ 顺序消息的实现方式
|
消息中间件 监控 NoSQL
Rabbmit 重复消费的问题
最近遇到一个奇怪的问题,消费者在批量消费消息时,遇到该批次中出现部分重复消费导致业务异常。这些异常集中在某一时刻附近。
214 0
|
消息中间件 存储 NoSQL
该如何保证消息不被重复消费
该如何保证消息不被重复消费
201 0
|
消息中间件 存储 网络协议
大厂都是如何处理重复消息的?
消息消费失败,很多框架会自动执行重试,而重试就产生了重复消息。 MQTT协议给出三种传递消息时能够提供的
283 0
|
消息中间件 存储 RocketMQ
【视频】顺序消息| 学习笔记
快速学习【视频】顺序消息
【视频】顺序消息| 学习笔记
|
消息中间件 Java 开发者
消息类型-顺序消息|学习笔记
快速学习消息类型-顺序消息
122 0
消息类型-顺序消息|学习笔记
|
存储 消息中间件 Linux
多类型业务消息专题-顺序消息 | 学习笔记
快速学习多类型业务消息专题-顺序消息
多类型业务消息专题-顺序消息 | 学习笔记