首页 > 其他分享 >消息队列常见问题总结

消息队列常见问题总结

时间:2022-08-25 23:35:33浏览次数:101  
标签:总结 常见问题 队列 系统 发送 消费 消息 序号

消息队列常见问题总结

作者:Grey

原文地址:

博客园:消息队列常见问题总结

CSDN: 消息队列常见问题总结

说明

本文是极客时间消息队列高手课的学习笔记

消息队列的主要作用

解耦

如果采用推送的方式,A 系统通过接口调用发送数据到 B、C、D 三个系统,A 系统的维护成本就非常的高,而且 A 系统要时时刻刻考虑B、C、D 四个系统如果出现故障该怎么办?使用消息队列就可以解决这个问题。A 系统只负责生产数据,不需要考虑消息被哪个系统来消费。

异步

A 系统需要发送个请求给 B 系统处理,由于 B 系统需要查询数据库花费时间较长,以至于 A 系统要等待 B 系统处理完毕后再发送下个请求,造成 A 系统资源浪费。使用消息队列后,A 系统生产完消息后直接丢进消息队列,不用等待 B 系统的结果,直接继续去干自己的事情了。

削峰

A 系统调用 B 系统处理数据,每天 0 点到 12 点,A 系统风平浪静,每秒并发请求数量就 100 个。结果每次一到 12 点 ~ 13 点,每秒并发请求数量突然会暴增到 1 万条。但是 B 系统最大的处理能力就只能是每秒钟处理 1000 个请求,这样系统很容易就会崩掉。这种情况可以引入消息队列,把请求数据先存入消息队列中,消费系统再根据自己的消费能力拉取消费。

消息队列的有什么局限性?

首先,消息队列会降低系统的可用性,因为引入消息队列,就等于引入多一种外部依赖,多一种外部依赖,挂掉的可能性就多一点;

其次,消息队列会使得系统复杂度提高,比如:需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题;

最后,使用消息队列,要考虑一致性问题:A 系统处理完了直接返回成功了,但问题是:要是 B、C、D 三个系统那里,B 和 D 两个系统写库成功了,结果 C 系统写库失败了,就造成数据不一致了。

如何保证消息队列的高可用?

RabbitMQ 使用的是 镜像集群模式。
Kafka 使用的是 partition和 replica 模式来保证高可用。

如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

可以在写数据时,先根据主键查一下这条数据是否存在,如果已经存在则 update;

数据库的唯一键约束也可以保证不会重复插入多条,因为重复插入多条只会报错,不会导致数据库中出现脏数据;

如果是写 Redis,就没有问题,因为 set 操作是天然幂等性的。

如何保证消息不丢失?

在生产阶段,你需要捕获消息发送的错误,并重发消息。
在存储阶段,你可以通过配置刷盘和复制相关的参数,让消息写入到多个副本的磁盘上,来确保消息不会因为某个 Broker 宕机或者磁盘损坏而丢失。
在消费阶段,你需要在处理完全部消费业务逻辑之后,再发送消费确认。
在 Producer 端,我们给每个发出的消息附加一个连续递增的序号,然后在 Consumer 端来检查这个序号的连续性。如果没有消息丢失,Consumer 收到消息的序号必然是连续递增的,或者说收到的消息,其中的序号必然是上一条消息的序号 +1。如果检测到序号不连续,那就是丢消息了。还可以通过缺失的序号来确定丢失的是哪条消息,方便进一步排查原因。大多数消息队列的客户端都支持拦截器机制,你可以利用这个拦截器机制,在 Producer 发送消息之前的拦截器中将序号注入到消息中,在 Consumer 收到消息的拦截器中检测序号的连续性,这样实现的好处是消息检测的代码不会侵入到你的业务代码中,待你的系统稳定后,也方便将这部分检测的逻辑关闭或者删除。

消息积压如何处理?

能导致积压突然增加,最粗粒度的原因,只有两种:要么是发送变快了,要么是消费变慢了。大部分消息队列都内置了监控的功能,只要通过监控数据,很容易确定是哪种原因。如果是单位时间发送的消息增多,比如说是赶上大促或者抢购,短时间内不太可能优化消费端的代码来提升消费性能,唯一的方法是通过扩容消费端的实例数来提升总体的消费能力。如果短时间内没有足够的服务器资源进行扩容,没办法的办法是,将系统降级,通过关闭一些不重要的业务,减少发送方发送的数据量,最低限度让系统还能正常运转,服务一些重要业务。还有一种不太常见的情况,你通过监控发现,无论是发送消息的速度还是消费消息的速度和原来都没什么变化,这时候你需要检查一下你的消费端,是不是消费失败导致的一条消息反复消费这种情况比较多,这种情况也会拖慢整个系统的消费速度。如果监控到消费变慢了,你需要检查你的消费实例,分析一下是什么原因导致消费变慢。优先检查一下日志是否有大量的消费错误,如果没有错误的话,可以通过打印堆栈信息,看一下你的消费线程是不是卡在什么地方不动了,比如触发了死锁或者卡在等待某些资源上了。

消息过期了怎么办?

我们可以采取一个方案,就是批量重导。就是大量积压的时候,直接丢弃数据了,然后等过了高峰期以后开始写程序,将丢失的那批数据一点一点的查出来,然后重新灌入 MQ 里面去,把丢的数据给补回来。

标签:总结,常见问题,队列,系统,发送,消费,消息,序号
From: https://www.cnblogs.com/greyzeng/p/16626177.html

相关文章

  • leetcode225-用队列实现栈
    用队列实现栈classMyStack{LinkedList<Integer>list=newLinkedList<>();publicMyStack(){}publicvoidpush(intx){list.a......
  • 2022/8/25 总结
    A.幸福考场上没想起矩阵,写了个\(\mathtt{O(n)}\)的暴力,得\(\mathtt{70pts}\);Solution矩阵乘法。对\(F_n\)进行化简,就可以化得一个式子:\(F_n=F_{n-1}+F_{n-2}......
  • 【索引】Mysql索引常见问题
    1、什么是索引:索引是一种数据结构,用来提高在数据表中的数据查询效率,同时也是随机读和有效排序的基础。2、为什么使用索引:根本原因在于磁盘速度与内存速度差距甚大,所......
  • ZLOJ 练习69 总结
    writtenon2022-08-17打得还可以虽然又是倒一hh前三题中第一题贪心稍微注意一下,想了一段时间还算可以。可以看一下第四题。这题最大的启示就是:要求的东西只关注最后的......
  • 如何统计子树内控制深度的权值和 && ZLOJ 练习73 C 谈笑风生 & ZLOJ 练习17 B 王子 の
    writtenon2022-08-23两道题好像是一模一样的类型,特此总结缅怀我逝去的70分,,谈笑风生:王子:数据范围均在\(10^5\)级别王子那题给的更明显一点,就是控制深度,求一棵......
  • ZLOJ 练习74 总结
    writtenon2022-08-17打得还可以虽然又是倒一hh前三题中第一题贪心稍微注意一下,想了一段时间还算可以。可以看一下第四题。这题最大的启示就是:要求的东西只关注最后的......
  • VUE 基础知识总结
    VUE的介绍VUE的导包<!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title><!--开发环境版本--><scriptsrc="https://cdn.jsdel......
  • 【FAQ】统一扫码服务常见问题
    ​ 1、华为统一扫码服务在控制台打印的日志如何关闭?​答:非常抱歉,目前扫码SDK未提供相关api可以关闭日志打印。 2、统一扫码服务支持同时识别多个一维码吗?​答:非常......
  • 8.24总结
    寿司考场上我对于这道题第一眼感觉是DP(反正不会是数据结构),但n的数据范围太大了,我没有想到O(n)的DP。于是考虑是否是贪心,但考场上我推出的贪心式子有问题。我是通过枚举每......
  • swagger错误总结
    1.按照步骤一步步做,pom依赖,类配置,检查注解有无,是否冲突,路径是否正确,是否与其他路径冲突。2.看pom依赖与sprignboot版本是否对应,一般2.2.1release对应2.7的swagger3.url......