当前位置: 首页 > news >正文

业务上需要顺序消费,怎么保证时序性?

消息传输和消费的有序性,是消息队列应用中一个非常重要的问题,在分布式系统中,很多业务场景都需要考虑消息投递的时序。例如,电商中的订单状态流转、数据库的 binlog 分发,都会对业务的有序性有要求。今天我们一起来看下,消息队列顺序消费的相关内容。

消息顺序消费有哪些困难

我们知道,消息队列中的队列是一个有序的数据结构,消息传递是顺序的,但在实际开发中,特别是在分布式场景下,消息的有序性是很难保证的,那么为什么实现有序性这么困难呢?下面进行拆解。

分布式的时钟问题

有序性可以分为业务上的有序和时间上的有序,先看一下时钟上的有序。在分布式环境下,消息的生产者、消费者和队列存储,可能分布在不同的机器上,不同的机器使用各自的本地时钟,由于服务器存在时钟偏斜等问题,本地时间会出现不一致,所以不能用消息发送和到达的时间戳作为时序判断标准。另一方面,分布式系统下缺乏全局时钟,这就使得绝对的时间顺序实现起来更加困难。

消息发送端和消费端的集群

在目前大多数消息队列的应用中,生产者和消费者都是集群部署,通过 ProducerGroup 和 ConsumerGroup 的方式来运行。

生产者如果存在多个发送实例,那么各个发送方的时间戳无法同步,所以消息发送端发送时的时序不能用来作为消息发送的有序判断。

同样的,消费端可能存在多个实例,即使队列内部是有序的,由于存在消息的分发过程,不同消费实例的顺序难以全局统一,也无法实现绝对的有序消费。

消息重传等的影响

我们知道,消息队列在传输消息时,可能会出现网络抖动导致的消息发送失败等,对这种场景的兼容,一般是通过进行合理地重传。消息的重传发生在什么时候是不可预知的,这也会导致消息传输出现乱序。

网络及内部并发

消息生产者集群或者消费端集群的方式,无法保证消息的绝对时序,如果只有一个消费端或者只有一个生产端呢?可以考虑这样一个场景,如果单纯地依靠消息队列本身来保证,那么在跨实例的情况下,因为网络传输的不稳定会有先后顺序,以及内部消费的并发等,仍然无法实现绝对有序。

通过上面的分析可以看到,保证消息绝对的有序,实现起来非常困难,除非在服务器内部,并且一个生产者对应一个消费者。但是这种情况的消息队列肯定是无法在实际业务中应用的,那么解决消息队列的有序性有哪些手段呢?下面从消息队列本身,以及业务设计上进行分析。

不同消息队列对顺序消费的保证

消息传输的有序性和不同的消息队列,不同业务场景,以及技术方案的实现细节等都有关系,解决消息传输的有序性,需要依赖消息队列提供对应的方式。

从消息队列自身的角度,可以分为全局有序和局部有序。当前大部分消息队列的应用场景都是集群部署,在全局有序的情况下,无法使用多分区进行性能的优化。在实际开发中,一般是应用局部有序,把业务消息分发到一个固定的分区,也就是单个队列内传输的方式,实现业务上对有序的要求。

以 Kafka 和 RocketMQ 为例,都实现了特定场景下的有序消息。

Kafka 顺序消息

Kafka 保证消息在 Partition 内的顺序,对于需要确保顺序的消息,发送到同一个 Partition 中就可以。单分区的情况下可以天然满足消息有序性,如果是多分区,则可以通过制定的分发策略,将同一类消息分发到同一个 Partition 中。

例如,电商系统中的订单流转信息,我们在写入 Kafka 时通过订单 ID 进行分发,保证同一个订单 ID 的消息都会被发送到同一个 Partition 中,这样消费端在消费的时候,可以保证取出数据时是有序的。

一个比较特殊的情况是消息失败重发的场景,比如同一个订单下的消息 1 和 2,如果 1 发送失败了,重发的时候可能会出现在 2 的后边,这种情况可以通过设置“max.in.flight.requests.per.connection”参数来解决,该参数可以限制客户端能够发送的未响应请求的个数,还可以在一定程度上避免这种消息乱序。

RocketMQ 顺序消息

RocketMQ 对有序消息的保证和 Kafka 类似,RocketMQ 保证消息在同一个 Queue 中的顺序性,也就是可以满足队列的先进先出原则。

如果把对应一个业务主键的消息都路由到同一个 Queue 中就可以实现消息的有序传输,并且 RocketMQ 额外支持 Tag 的方式,可以对业务消息做进一步的拆分,在消费时相对更加灵活。

从业务角度保证顺序消费

在我之前的项目中,消息消费的有序性,归根到底是一个业务场景的设计问题,可以在业务中进行规避,或者通过合理的设计方案来解决。

消息传输的有序性是否有必要

山不过来,我就过去,解决一个问题,如果从正面没有很好的解决方案,那么我们就可以考虑是否绕过它。考虑在你的业务中,是否必须实现绝对的消息有序,或者是否必须要有消息队列这样的技术手段。

比如在一个订单状态消息流转的业务场景中,订单会有创建成功、待付款、已支付、已发货的状态,这几个状态之间是单调流动的,也就是说,订单状态的更新需要保证有序性。考虑一下,如果我们要实现的功能是根据发货的状态,进行物流通知用户的功能,实际上因为这个状态是单调不可逆向的,我们可以忽略订单状态的顺序,只关注最后是否已发货的状态。

也就是说,在这个场景下,订单状态流转虽然是要考虑顺序,但是在具体的这个功能下,实际上不需要关注订单状态消息消费的时序。

业务中如何实现有序消费

除了消息队列自身的顺序消费机制,我们可以合理地对消息进行改造,从业务上实现有序的目的。具体的方式有以下几种。

  • 根据不同的业务场景,以发送端或者消费端时间戳为准

比如在电商大促的秒杀场景中,如果要对秒杀的请求进行排队,就可以使用秒杀提交时服务端的时间戳,虽然服务端不一定保证时钟一致,但是在这个场景下,我们不需要保证绝对的有序。

  • 每次消息发送时生成唯一递增的 ID

在每次写入消息时,可以考虑添加一个单调递增的序列 ID,在消费端进行消费时,缓存最大的序列 ID,只消费超过当前最大的序列 ID 的消息。这个方案和分布式算法中的 Paxos 很像,虽然无法实现绝对的有序,但是可以保证每次只处理最新的数据,避免一些业务上的不一致问题。

  • 通过缓存时间戳的方式

这种方式的机制和递增 ID 是一致的,即当生产者在发送消息时,添加一个时间戳,消费端在处理消息时,通过缓存时间戳的方式,判断消息产生的时间是否最新,如果不是则丢弃,否则执行下一步。

总结

本文讨论了消息队列有序性的话题,消息的有序性可以分为时间上的有序和业务上的有序。

通过上面的分析可以看到,绝对的时间有序实现起来是非常困难的,即使实现了这样的消息队列,但在实际应用中的意义并不大。消息队列只是一个消息传输的解决方案,不是软件开发中的银弹,一般来说,我们可以通过业务中不同的场景,进行合理的设计,实现业务上的有序性。

现在你可以思考一下,在你的项目中,哪些场景要求消息传输和消费的有序性,具体是如何解决的?欢迎留言进行分享。

相关文章:

业务上需要顺序消费,怎么保证时序性?

消息传输和消费的有序性,是消息队列应用中一个非常重要的问题,在分布式系统中,很多业务场景都需要考虑消息投递的时序。例如,电商中的订单状态流转、数据库的 binlog 分发,都会对业务的有序性有要求。今天我们一起来看…...

ubuntu 开机提示 you are in emergency mode,journalctl -xb

进入系统界面 回车输入: journalctl -xb -p3 查看出问题的盘符类型。 然后 lsblk 查看挂载情况 我的是/dev/sda3没有挂载上,对应/home目录,注意这时候不要直接mount 需要先修复 fsck -y /dev/sda3等待修复完成,在重新挂载 moun…...

【Hadoop面试】HDFS读写流程

HDFS(Hadoop Distributed File System)是GFS的开源实现。 HDFS架构 HDFS是一个典型的主/备(Master/Slave)架构的分布式系统,由一个名字节点Namenode(Master) 多个数据节点Datanode(Slave)组成。其中Namenode提供元数…...

B01、JVM与Java体系结构-01

字节码与多语言混合编程 字节码概述: 我们平时说的java字节码,指的是用java语言编译成的字节码。准确的说任何能在jvm平台上执行的字节码格式都是一样的。所以应该统称为:jvm字节码。不同的编译器,可以编译出相同的字节码文件&…...

Python:Jupyter

Jupyter是一个开源的交互式计算环境,由Fernando Perez和Brian Granger于2014年创立。它提供了一种方便的方式来展示、共享和探索数据,并且可以与多种编程语言和数据格式进行交互。Jupyter的历史可以追溯到2001年,当时Fernando Perez正在使用P…...

macos苹果电脑开启tftp server上传fortigate60e固件成功

cat /System/Library/LaunchDaemons/tftp.plist<?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist…...

如何使用ArcGIS Pro裁剪影像

对影像进行裁剪是一项比较常规的操作&#xff0c;因为到手的影像可能是多种范围&#xff0c;需要根据自己需求进行裁剪&#xff0c;这里为大家介绍一下ArcGIS Pro中裁剪的方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的影像和行政区…...

Tekton 构建容器镜像

Tekton 构建容器镜像 介绍如何使用 Tektonhub 官方 kaniko task 构建docker镜像&#xff0c;并推送到远程dockerhub镜像仓库。 kaniko task yaml文件下载地址&#xff1a;https://hub.tekton.dev/tekton/task/kaniko 查看kaniko task yaml内容&#xff1a; 点击Install&…...

netty-daxin-4(httpwebsocket)

文章目录 学习链接http服务端NettyHttpServerHelloWorldServerHandler 客户端ApiPost websocket初步了解为什么需要 WebSocket简介 浏览器的WebSocket客户端客户端的简单示例客户端的 APIWebSocket 构造函数webSocket.readyStatewebSocket.onopenwebSocket.onclosewebSocket.ο…...

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《市场环境下考虑全周期经济效益的工业园区共享储能优化配置》

这个标题涉及到工业园区中共享储能系统的优化配置&#xff0c;考虑了市场环境和全周期经济效益。以下是对标题中各个要素的解读&#xff1a; 市场环境下&#xff1a; 指的是工业园区所处的商业和经济背景。这可能包括市场竞争状况、电力市场价格波动、政策法规等因素。在这一环…...

WPF——命令commond的实现方法

命令commond的实现方法 属性通知的方式 鼠标监听绑定事件 行为&#xff1a;可以传递界面控件的参数 第一种&#xff1a; 第二种&#xff1a; 附加属性 propa&#xff1a;附加属性快捷方式...

信息收集 - 域名

1、Whois查询: Whois 是一个用来查询域名是否已经被注册以及相关详细信息的数据库(如:域名所有人、域名注册商、域名注册日期和过期日期等)。通过访问 Whois 服务器,你可以查询域名的归属者联系方式和注册时间。 你可以在 域名Whois查询 - 站长之家 上进行在线查询。 2、…...

基于YOLOv8深度学习的路面标志线检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

leetCode算法—1.两数之和

难度&#xff1a;* 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你…...

oracle 设置访问白名单

有相关安全策略会要求部分 ip 禁止访问oracle数据库&#xff0c;那么如何实现对IP的白名单设置呢&#xff1f;又如何细分到对用户的限制访问呢&#xff1f;本文将介绍方法给大伙。 1、禁止IP访问数据库&#xff08;修改sqlnet.ora方式实现&#xff09; vi $ORACLE_HOME/network…...

Flink系列之:窗口关联

Flink系列之&#xff1a;窗口关联 一、窗口关联二、INNER/LEFT/RIGHT/FULL OUTER三、SEMI四、ANTI五、限制 一、窗口关联 适用于流、批窗口关联就是增加时间维度到关联条件中。在此过程中&#xff0c;窗口关联将两个流中在同一窗口且符合 join 条件的元素 join 起来。窗口关联…...

Eolink 两项产品入选 2023 年广东省名优高新技术产品名录!

近日&#xff0c;2023 年广东省名优高新技术产品正式名单已经发布&#xff0c;Eolink 旗下两项产品荣幸入选&#xff01; “广东省名优高新技术产品”是广东省对高新技术产品领域的升级和优化的重要措施。名优产品的评选不仅强调了技术的先进性&#xff0c;更对产品的质量、市…...

054:vue工具 --- BASE64加密解密互相转换

第054个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…...

自动驾驶学习笔记(二十)——Planning算法

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo 社区开发者圆桌会》免费报名—>传送门 文章目录 前言 参考线平滑 双层状态机 EM Planner …...

adb的使用

Adb windows 环境搭建 &#xff08;1&#xff09;将adb包安装或者解压到一个路径&#xff0c;并拿到adb.exe所在的路径值&#xff0c;例如,D:\Tools\adb &#xff08;2&#xff09;将路径值放进windows环境变量 我的电脑&#xff08;此电脑图标&#xff09;右键–》 选择“属…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...