消息队列前文目录

消息队列初见:一起聊聊引入系统mq 之后的问题 https://www.cnblogs.com/yizhiamumu/p/16573472.html

分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html

分布式事务原理及解决方案案例 https://www.cnblogs.com/yizhiamumu/p/16662412.html

消息队列为什么选用redis?聊聊如何做技术方案选型 https://www.cnblogs.com/yizhiamumu/p/16690033.html

消息队列的对比测试与RocketMQ使用扩展 https://www.cnblogs.com/yizhiamumu/p/16677881.html

消息队列的一些场景及源码分析,RocketMQ使用相关问题及性能优化 https://www.cnblogs.com/yizhiamumu/p/16694126.html

一:为什么使用MQ

中小公司系统一开始体量较小,后来随着用户量逐渐扩大,需要把很多业务进行拆分,因此引入消息队列来优化问题。

其通用的使用场景可以简单地描述为:

当不需要立即获得结果,但是并发量又需要进行控制的时候,就是需要消息队列的时候。

二:消息队列应用的几大场景:

解耦

多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败。

具体场景:用户注册,系统发送邮件并验证短信。

一般情况下,串行方式,并行方式均可。

或使用消息队列,注册信息写入到消息队列。

或电商交易系统,交易服务发送消息,要生成订单,要扣减库存,要物流发货。

异步

多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间。

具体场景:人脸识别系统。用户上传图片,调用人脸识别,调用完成后再返回信息。该方法的缺点是:1 人脸识别失败导致图片上传失败;2 延迟高,需要系统处理完成后再返回客户端,即使用户不需要立即知道结果;3 图片上传系统和人脸识别系统互相调用,耦合度高。

客户端上传图片后,图片上传系统将图片信息如uid, 批次写入mq, 直接返回成功。人脸识别系统定时从mq 中取数据,完成对新增图片的识别。

此时,图片上传系统不需要关心人脸识别系统是否对这些图片信息的处理,以及何时对这些图片的处理。事实上,由于用户并不需要立即知道人脸识别的结果,人脸识别系统可以选择不同的调度策略,按忙时、闲时、正常时间对队列中的图片信息进行处理。

消峰

广泛应用于秒杀或抢购活动,避免流量过大导致系统挂掉。

具体场景:秒杀活动一般瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚至崩溃。而加入mq 后,系统可以从mq 中取数据,相当于mq 做了一次缓冲。

优点:

  • 1 请求先入mq, 而不是由业务系统直接处理,做了一次缓冲,极大减少业务处理系统的压力。
  • 2 队列长度可以做限制,事实上,秒杀时,后入队列的用户无法秒杀到商品,这些请求可以直接被抛弃,返回活动已结束或商品已售完。

消息驱动的系统

系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,多个消费者负责对消息进行处理。

具体场景:用户新上传一批照片,人脸识别系统需要对这个用户的所有照片进行聚类,聚类完成后由对帐系统重新生成用户的人脸索引加快查询。这三个子系统间由mq 连接起来,前一个阶段处理结果放入队列中,后一个阶段从队列中获取消息继续处理。

优点:

  • 避免了直接调用下一个系统导致当前系统失效
  • 每个子系统对于消息的处理方式可以更灵活,可以选择接收到消息 时就处理,可以选择定时处理,也可以划分时间段按不同处理速度处理。

三:MQ 存在问题及场景优化

3.1 重复消费问题

问题出现的场景:

  • 消息生产者产生了重复的消息
  • kafka 和 RocketMQ 的 offset 被回调了
  • 消息消费者确认失败
  • 消息消费者确认超时
  • 业务系统主动发起重试
解决方案

不管是生产者产生的重复消息,还是消费者导致的重复消息,我们都可以在消费者中解决这个问题。这就需要我们做幂等设计。

增加一张消费消息表,使用messageId 做唯一索引。在处理逻辑前,先根据messageId 查询一下该消息有没有处理过,如果已经处理过则直接返回,如果没有处理过,则继续做业务处理

3.2 数据一致性问题(异步分布式事务问题)

问题出现的场景:

当服务是同步调用的时候,我们可以使用本地事务来控制数据一致性。但异步调用会存在数据不一致的问题。如商品订单下单成功,但是扣减库存失败,就是造成超卖问题。

解决方案

数据一致性分为:强一致性,弱一致性,最终一致性。

mq 为了性能使用的是最终一致性,那么必定会出现数据不一致的问题。这类问题大概率是因为消费者读取消息后,业务逻辑处理失败导致的。这个时候可以增加重试机制。

重试可以分为同步重试和异步重试。消息量比较小的业务场景,可以采用同步重试,如果消息处理失败立即重试3-5次,如果还失败则写入记录表中。如果消息量比较大,则采用异步方式。在处理失败后立即写入重试表,有个job 专门重定时重试。

还有一种做法,如果消费失败,自己给同一个topic 发一条消息,在后面的某个时间点自己又会消费到那一条消息,起到了重试的效果。如果对消息顺序要求不高的场景。这种做法适合对消费顺序要求不高的场景。

需要事务强一致的,不用消息异步,如下单、减库存要放在一个事务时在,加积分等业务放在mq 中异步处理。

3.3 消息丢失问题

问题出现的场景:

  • 生产者产生消息时,由于网络原因发送到mq 失败
  • mq 服务器持久化,存储磁盘时出现异常
  • kafka 和 rocketMQ 的offset 被回调时,略过了很多消息
  • 消费者刚读取消息,已经ack 确认,但是业务还没处理完,服务被重启了。

生产者、消费者、服务器都可能产生问题,最终的结果会导致消费者无法正确的处理消息而导致数据不一致的情况。

解决方案

增加一张消息发送表。

  • 当生产者发完消息后,会往该表中写入一条数据,状态status 标记为待确认
  • 如果消费者读取消息后,调用生产者api 更新该消息status 为已确认
  • 有个job 每隔一段时间检查一次消息发送表,如果执行后还有状态是待确认的消息,则认为该消息丢失,重发该消息。

3.4 消息顺序问题

问题出现的场景:

如商品订单-支付-完成-退货等状态,如果订单数据作为 消息体,就会涉及顺序问题。如果先支付后下单,是不可以的。

这样的问题场景有很多,比如:

  • kafka 同一个partition 中能保证顺序,但是不同的partition 无法保证顺序
  • rabbitMQ 的同一个queue 能够保证顺序,但是如果多个消费者同一个queue 也会有顺序问题
  • 如果消费者使用多线程消费消息,无法保证顺序
  • 如果生产者发送到mq 中的路由规则跟消费者不一样,也无法保证顺序
解决方案

首先我们需要确认,消费者是否真的需要知道中间状态,只知道最终状态行不行。

其实很多时候我们真的需要知道的最终状态,这样我们可以把流程优化一下:

这种流程可以解决大部分的消息顺序问题。但是如果真的有需要保证顺序的需求,可以将订单号路由到不同的partition,同一个订单号的消息,每次发送到同一个partition

3.5 消息堆积问题

问题出现的场景:

很多时候,由于某些批处理或其他原因,导致消费速度小于生产速度,这样会直接导致消息堆积问题,从而影响业务功能。

比如开通会员,如果消息出现堆积会导致用户下单后,很久才变会员。这种情况肯定会引起大量用户投诉。

解决方案

看消息是否需要保证顺序。如果不需要保证顺序,可以读取消息之后用多线程处理业务逻辑。

这样就能增加业务逻辑处理速度,解决消息堆积问题。但是线程池的核心线程数和最大线程数需要合理配置,不然可能会浪费系统资源。

如果需要保证顺序,可以读取消息后将消息按照一定的规则分发到多个队列中,然后在队列中用单线程处理。

rabbitmq ,activemq , rocketmq, kafka 对比

引入mq 之后的问题

本来我们需要保证系统服务可用就可以了,现在引入新的服务,我们要保证mq 的可用,系统的可用性和复杂性都会有新的要求。

文::一只阿木木

消息队列初见:一起聊聊引入系统mq 之后的问题的更多相关文章

  1. 为什么要用消息队列 及 自己如何设计一个mq架构

    1. 解耦:如左图, 系统a因为业务需求需要调用系统b,后续因为业务需求可能需要改代码调用系统c,甚至还要考虑被调用的系统挂了访问超时的问题.耦合性太高! 如右图, 系统a产生一条数据发送到消息队列里 ...

  2. 消息队列的一些场景及源码分析,RocketMQ使用相关问题及性能优化

    前文目录链接参考: 消息队列的一些场景及源码分析,RocketMQ使用相关问题及性能优化 https://www.cnblogs.com/yizhiamumu/p/16694126.html 消息队列 ...

  3. 一个用消息队列 的人,不知道为啥用 MQ,这就有点尴尬

    消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: 小A,工作于传统软件行业(某社保局的软件外包公司),每天工作内容就是和产品聊聊需求,改改业务逻辑.再不然就是和运营聊聊天,写几个SQL, ...

  4. 转载:消息队列MQ

    本文大概围绕如下几点进行阐述: 为什么使用消息队列? 使用消息队列有什么缺点? 消息队列如何选型? 如何保证消息队列是高可用的? 如何保证消息不被重复消费? 如何保证消费的可靠性传输? 如何保证消息的 ...

  5. IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

    1.引言 消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一. 消息从发送者到接收者的典型传递方式有两种: 1)一种我 ...

  6. 天天都用消息队列,却不知道为啥要用MQ,这就有点尴尬了

    1.为什么要使用消息队列? 分析:一个用消息队列的人,不知道为啥用,有点尴尬.没有复习这点,很容易被问蒙,然后就开始胡扯了. 回答:这个问题,咱只答三个最主要的应用场景(不可否认还有其他的,但是只答三 ...

  7. rabbit MQ 消息队列

    为什么会需要消息队列(MQ)? 一.消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ...

  8. 深入消息队列MQ,看这篇就够了!

    大厂面试爱问消息队列 MQ. 因为消息队列MQ,既是大型分布式系统不可缺少的中间件,也是高并发系统的基石中间件. 如果你想要快速掌握消息队列 MQ 最内核的知识,以及消息队列MQ的主流应用场景.主流产 ...

  9. 消费端如何保证消息队列MQ的有序消费

    消息无序产生的原因 消息队列,既然是队列就能保证消息在进入队列,以及出队列的时候保证消息的有序性,显然这是在消息的生产端(Producer),但是往往在生产环境中有多个消息的消费端(Consumer) ...

  10. (转)Linux环境进程间通信----系统 V 消息队列列

    转:http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.作为早期unix通 ...

随机推荐

  1. 推荐一枚宝藏Up主,顺便聊聊感想

    众所周知,B站是学习网站 最近发现一宝藏Up主,主要做科普,主题包括但不限于:大模型的底层算法.量子计算底层原理和硬件设计,以及其他物理或者自然科学主题,总体偏向于理工科. 值得推荐的理由:Up主对底 ...

  2. [rCore学习笔记 013]GDB跟踪程序

    题目要求 请学习 gdb 调试工具的使用(这对后续调试很重要),并通过 gdb 简单跟踪从机器加电到跳转到 0x80200000 的简单过程.只需要描述重要的跳转即可,只需要描述在 qemu 上的情况 ...

  3. [rCore学习笔记 08]内核第一条指令

    了解QEMU 启动指令 qemu-system-riscv64 \ -machine virt \ -nographic \ -bios ../bootloader/rustsbi-qemu.bin ...

  4. GIS前沿技术

    无论是初步接触到GIS的学生,还是对GIS已经有一定的了解的从业者,肯定都非常关心两个问题:GIS有没有发展前景,GIS有哪些应用价值? 关于这两个问题,笔者的答案是GIS作为一门融合了空间数据采集. ...

  5. Git 克隆仓库报unable to get local issuer certificate错误解决方法

    Git 克隆仓库报unable to get local issuer certificate错误解决方法 By:授客 QQ:1033553122 问题描述 克隆gitlab上的仓库,报错,如下 $ ...

  6. ComfyUI进阶:Comfyroll插件 (七)

    前言: 学习ComfyUI是一场持久战,而Comfyroll 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具.借助这些节点,用户可以在静态图 ...

  7. LeetCode122. 买卖股票的最佳时机 II

    题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/ 题目叙述: 给你一个整数数组 pri ...

  8. 安卓快速掌网络请求HttpUrlConnection,GET和getHttp相关示例

    HttpURLConnection 是 Java 标准库中的一部分,它不依赖于特定的 Android 版本.,从 Android 9(API 级别 28)开始,Google 官方推荐使用更现代化的网络 ...

  9. 【云服务器】记录使用腾讯云服务器搭建个人blog网站-【1】服务器配置

    服务器购买 第一次写博客,写的不好请见谅 腾讯云教育活动 配置还行,能搭建个网站了果断下单 选择系统 缺点(对我来说):参考于:人生不开窍:Windows Server各版本差异 不能安装window ...

  10. windows上传app到构建版本的方法

    ios打包好ipa文件后,ipa文件需要上架到app store,用户才能安装.而在app store里,无法直接将ipa上传,需要使用工具上传,但是官方提供的工具,比如xcode等只能安装在苹果电脑 ...