首页 > 其他分享 >MQ

MQ

时间:2024-09-27 18:22:41浏览次数:5  
标签:消费 系统 queue MQ 消息 consumer

为什么用MQ?

解耦:

  1. A系统向BCD系统发送数据,调用接口发送,如果新来的E系统需要数据,旧的D系统不需要数据,那么就需要频繁的修改A系统的代码,并且还需要考虑BCD系统挂掉的问题,数据非常重要的话,是要重发呢?还是暂时存起来?
  2. 但是如果使用MQ,A系统只需要考虑把数据发送到MQ就不用操心别的了,不用管发送给谁,不用考虑人家是否调用成功/失败,是否超时?新来的系统需要就消费MQ的消息,不需要了就不消费
  3. 通过MQ这种pub/sub发布订阅模型,A系统就能和BCD系统彻底解欧,一个系统调用了多个系统,调用复杂,维护难度高,但是这个调用不需要同步调用接口才能实现,那么就可以使用MQ异步化解藕,

异步:

  1. A系统接收请求,需要入库123,同步定义的接口内部处理方式的处理时间为5(发送请求) + 300+500+800ms(处理请求),响应给用户的,用户等待时间过长
  2. 如果采用MQ异步的方式,A系统发送消息到MQ,然后直接A系统直接返回结果,剩下的入库操作123由其它服务异步完成,给用户那么只需5ms,响应时间非常短。

削峰:

  1. 某个时间段,每秒并发请求数量(QPS)会增加至5000左右,请求会打到mysql,mysql的并发2000就差不多了,这么大的并发量会把mysql打挂,导致系统崩溃
  2. 如果使用MQ,请求写入到MQ中,A系统根据自身消费能力去MQ中慢慢消费,这样的话服务mysql不会被打挂,但是MQ会有大量消息堆积

缺点:

  1. MQ挂掉,整个系统就完了,系统可用性降低了
  2. 发送消息如何保证没重复消费,如何处理消息丢失,如何保证消息处理的顺序性
  3. 异步处理时,你返回给用户成功,但是入库123操作有异常,你这到底是成功还是失败?数据一致性怎么保证?

消息队列选型?

  1. 吞吐量,达到10万级别
  2. 时效性,在ms级别
  3. 高可用性,分布式架构,一台挂了另一台能顶上
  4. 消息可靠性,经过参数优化配置可以做到0丢失

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

  1. Producer 与 NameServer集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Broker Master/Slave 建立长连接,且定时向 Broker 发送心跳。Producer 只能将消息发送到 Broker master,但是 Consumer 则不一样,它同时和提供 Topic 服务的 Master 和 Slave建立长连接,既可以从 Broker Master 订阅消息,也可以从 Broker Slave 订阅消息。

如何保证消息不被重复消费?

  1. 首先重复消费很正常,各种意外情况都有可能导致重复消费,这不是消息队列来保证的,而是我们自己要保证的,比如kafaka的消费数据后提交offset,然后系统重启可以根据offset继续消费,但是如果kill进程重启系统,有可能出现offset没提交到zookeeper中进而zookeeper也无法给kafaka,那么下次重启就会重复消费之前消费过的信息,如果消费消息是插入数据库行为就会导致数据重复插入
  2. 重复消费不可怕,只要做好幂等即可,比如插入数据时先判断一下是否已经消费过了,具体做就是根据业务场景来做了,比如数据唯一索引(唯一主键),redis的写入set集合,发送消息时有全局唯一id,这样同一条消息的全局唯一id一样,消费第二次时判断一下就能判断出来已经消费过了

如何保证消息可靠性(处理消息丢失问题)?

  1. 生产者到MQ丢失问题
    • 事务机制,发送消息失败,生产者收到异常报错,可以回滚事务,尝试重发消息,发送消息成功可以提交事务,缺点就是事务是同步的,事务开启后到提交/回滚之前都是阻塞的
    • 开启生产者的confirm机制,消息发送到MQ后,成功则返回ack消息,MQ接受失败则回调nack接口告知生产者失败,可以重试,好处就是confirm机制是异步的,发送消息后可以继续发送消息做其他操作,MQ会自动异步回调nack接口
  2. MQ自身丢失问题
    • 开启持久化机制保存消息到磁盘中,除非极小概率发生还没持久化就挂掉的问题,可能性很小
    • 可以配合confim机制,只有消息持久化到磁盘中才返回ack,如果没有ack/回调了nack接口,那么生产者还可以重试,重发消息
  3. 消费端丢失问题
    • 也就是刚消费到数据,还没处理,进程挂了,比如重启了,那么MQ认为你消费了数据就相当于丢失了
    • 利用MQ的ack机制,关闭自动ack,手动进行ack,只有处理完才ack,这样这边没处理完,不会ack,MQ那边不会丢失消息

如何保证消息消费的顺序?

  1. mysql的binlog日志发送到mq,然后再消费出来执行数据同步,其中增删改的顺序就很重要

  2. 问题就在于一个queue绑定多个消费者consumer,同一条消息只会被一个消费者consumer消费,这样对于消费顺序有要求的场景就无法区分谁先消费,谁先处理,无法保证顺序

  3. 解决方案:

    • 一个queue对应一个consumer,弄多个queue,这样发数据多份到每个queue,每一个消费者consumer消费的都是有序的
    • 或者一个queue对一个consumer,维护多个内存队列
  4. 场景:

    订单创建,订单付款,订单完成,同一个订单有序即可,不同订单不用有序,同一分区内的消息保证顺序,不同分区之间的消息顺序不做要求

  5. RabbitMQ出现消费顺序错乱的情况

    • 为了提高处理效率,一个queue存在多个consumer
    • 一个queue只存在一个consumer,但是为了提高处理效率,consumer中使用了多线程进行处理----->不能解决
  6. 保证消息顺序性的方法:

    • 将原来的一个queue拆分成多个queue,每个queue都有一个自己的consumer。该种方案的核心是生产者在投递消息的时候根据业务数据关键值(例如订单ID哈希值对订单队列数取模)来将需要保证先后顺序的同一类数据(同一个订单的数据) 发送到同一个queue当中,这样正常单线程消费就可以
    • 一个queue就一个consumer,在consumer中维护多个内存队列,根据业务数据关键值(例如订单ID哈希值对内存队列数取模)将消息加入到不同的内存队列中,然后多个真正负责处理消息的线程去各自对应的内存队列当中获取消息进行消费。同分区有序相同

标签:消费,系统,queue,MQ,消息,consumer
From: https://www.cnblogs.com/complexlong/p/18436333

相关文章

  • Spring Boot 集成 RabbitMQ 发送延时消息
    1.SpringBoot集成RabbitMQ发送延时消息1.1.版本说明1.2.Spring配置1.3.定义常量1.4.配置交换机和队列1.5.测试1.SpringBoot集成RabbitMQ发送延时消息延时消息依赖于rabbitmq-delayed-message-exchangeRabbitMQ插件实现,Github地址,启用该插件后可......
  • RocketMQ的基本概念
    Producer:消息的发送者;举例:发信者Consumer:消息接收者;举例:收信者Broker:暂存和传输消息;举例:邮局NameServer:管理Broker;举例:各个邮局的管理机构Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息MessageQueue:相当于是To......
  • RocketMq知识总结及消息顺序性
    为什么选择RocketMq?几种MQ的区别:如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用Kafka是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规......
  • RabbitMQ基础知识
    1.1什么是MQ?消息队列(MessageQueue),是基础数据结构中“先进先出”的一种数据结构。一般用来解决应用解耦、异步消息、流量削峰等问题,实现高性能、高可用、可伸缩和最终一致性架构。RabbitMQ可以理解为一个邮箱,或者一个邮局,或者是一个邮递员,保证“张三”的信件最终传递......
  • fmql之linux启动文件大小
    想要从flash启动linux,但是flash同时也要存储数据,所以看看启动文件占多大内存。本是基于“fmql之ubuntu移植”的基础上继续进行的:fmql之ubuntu移植-CSDN博客目的:flash放启动文件,ubuntu18放到SD卡,且自启动。 NOW:flash可以烧写BOOT.bin,image.ub和ubuntu放到SD卡,MIO配置......
  • STM32F103C8T6+ESP8266+MQTT+EMQX完成数据上传和点灯环节
    本文参考以下文章:【最简单】STM32+ESP8266+MQTT+EMQX完成数据上传和点灯环节_stm32如何连接emqx-CSDN博客STM32+ESP8266通过MQTT协议连接本地EMQX(保姆级教学!资料开放!)_stm32驱动esp8266本地emqx-CSDN博客 一、在windows环境下或Ubuntu搭建EMQX云平台 参看这篇文章:搭建自己的M......
  • RabbitMq 入门应用 提升性能 : 算法多阶段并行 (Python)
    大问题:我们有一个算法,它可以被分为多个阶段进行(顺序不可颠倒),每个阶段的性能和资源要求不同(且不均衡程度比较高);假设我们现在可以堆资源(较多的CPU和内存),如何将算法各个步骤拆分并进行性能均衡和实现,使得算法性能最大化以满足生产要求?多进程:由于算法有严格的顺序要求,如果是......
  • 搭建RocketMQ集群
    一、环境及准备集群环境:软件版本:部署前操作:关闭防火墙,关闭selinux(生产环境按需关闭或打开)同步服务器时间,选择公网ntpd服务器或者自建ntpd服务器[root@es1~]#crontab-l#为了方便直接使用公网服务器#updatetime*/5****/usr/bin/rdate-stime-b.nist.gov&>/dev/nul......
  • RocketMQ多master多salve集群搭建
    一、RocketMQ集群模式简介单Master方式风险比较大,一旦Broker重启或者宕机,将导致整个环境不可用,不建议线上使用.多Master模式一个集群中没有slave,全是master,例如2个master或者3个master.优点:配置简单,性能最好,单个Master宕机或重启对应用无影响,磁盘配置为RAID10时,......
  • RabbitMQ(兔子队列入门/消息队列)
    介绍(本笔记不涉及RabbitMQ的环境搭建,主要用于了解和上手使用RabbitMQ)RabbitMQ是一种消息队列,什么是消息队列?消息(Message):是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。**队列:**可以说是一个数据结构,可以存储数据,如下图,我们从右侧(队......