消息中间件

  消息队列已经逐渐成为企业应用系统内部通信的核心手段,它具有低耦合可靠投递广播流程控制最终一致性等一系列功能。
  消息队列是指利用高效可靠消息传递机制 进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。

当前业界开源的消息中间件:
  ActiveMQ,RabbitMQ,RocketMQ,Kafka,ZeroMQ等。其中应用广泛的是RabbitMQRocketMQKafka

选型问题

Springboot,SpringCloud默认支持的amqp就是RabbitMQ。

  1. 选择开源的,近几年比较流程,社区活跃
  2. 消息传递的可靠性,保证消息不会丢失
  3. 支持集群,包括横向扩展,单点故障都可以解决
  4. 性能要好,要能够满足业务要求

RabbitMQ

  开始是用于电信业务的可靠通信的,也是少有的几款支持AMQP协议的产品之一。

  优点:

  1. 轻量级,快捷,部署使用方便。
  2. 支持灵活的路由配置,RabbitMQ中,在生产者和队列之间有一个交换机模块,根据配置的路由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己定义。
  3. RabbitMQ的客户端支持大多数编程语言。

  缺点:

  1. 如果有大量消息堆积在队列中,性能会急剧下降。
  2. RabbitMQ的性能在RocketMQ 和Kafka中性能是最差的,每秒处理几万到几十万的消息,如果应用要求搞的性能,不要选择RabbitMQ。吞吐量低一点。
  3. RabbitMQ是Erlang开发的,功能扩展和二次开发代价很高。

RocketMQ

  是通过java实现了。借鉴了Kafka的设计并作了很多改进。RocketMQ主要用于有序,事务流计算,消息推送,日志流处理,binlog分发等场景。经理了数次双11考验,性能,稳定性可靠性没得说。

  优点:

  1. RocketMQ几乎具备了消息队列应该具备的所有特性和功能。
  2. java开发,阅读源码,二次开发比较方便。
  3. 性能比RabbitMQ高一个数量级。

  缺点:

  1. 和周围的整合和兼容不是很好。

Kafka

  Kafka的可靠性,稳定性和功能特性基本满足大多数的应用场景。和周围的兼容性也是数一数二的,尤其是大数据和流计算领域,几乎所有相关的开源软件都支持Kafka。

  Kafka是scala语言开发的,对批处理和异步处理做了大量的设计,因此Kafka可以得到非常高的性能。它的异步消息的发送和接收是三个之中最好的,处理数据量大概每秒几十万的消息。

  如果是异步消息,并且开启了压缩,kafka最终可以达到每秒2000w消息的级别。但是由于是异步的和批处理的,延迟也会高,不适合电商场景。

计较

在这里插入图片描述

MQ详细介绍

RabbitMQ

在这里插入图片描述

  1. Broker:一个RabbitMQ实例就是一个Broker。
  2. Virtual Host:虚拟主机。相当于Mysql的DataBase。一个Broker上可以存在多个Virtual Host。Virtual Host之间是相互隔离的。每个Virtual Host都拥有自己的队列交换机绑定权限机制。Virtual Host必须在连接时指定,默认的Virtual Host是/。
  3. Exchange:交换机。用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
  4. Queue:消息队列。用来保存消息直到发送给消费者。它是消息的容器。一个消息可投入一个或多个队列。
  5. Binding:绑定关系,用于消息队列和交换机之间关联。通过路由键(Routing Key)将交换机和消息队列关联起来。
  6. Channel:管道。一条双向数据流通道。
  7. Connection:生产者/消费者 与Broker之间的TCP连接。
  8. Publisher:消息生产者
  9. Consumer:消息消费者
  10. Message:消息。它由消息头消息体组成。 消息头则包括Routing-key,Priority(优先级)等。
RabbitMQ的交换机

  Exchange分发消息给Queue时,Exchange的类型对应不同的分发策略。有3中类型的Exchange:DirectFanoutTopic
  Direct:消息中的Routing Key如果和Binding中的Routing key完全一致,Exchange就会将消息分发到对应的队列中。
  Fanout:每个发到Fanout类型交换机的消息都会分发到所有绑定的队列上去。Fanout交换机没有Routing Key。它在三种类型的交换机中转发消息时最快的。
  Topic:Topic交换机通过模式匹配分配消息,将Routing key和某个模式进行匹配。它只能识别两个通配符:“#“和”*”。#匹配0个或多个单词,*匹配1个单词。

TTL

  生存时间。RabbitMQ支持消息的过期时间。一共两种。
  (1)在消息发送时进行指定。通过配置消息体的Properties,可以指定当前消息的过期时间。
  (2)在创建Exchange时指定。从进入消息队列开始计算,只要超过了队列的超时时间配置,那么消息会自动清除。

生产者消息确认机制
  1. Confirm机制
      消息的确认,是指生产者投递消息后,如果Broker收到消息,则会给生产者一个应答。
      (1)在channel上开启确认模式:channel.confirmSelect()。
      (1)在channel上开启监听:addConfirmListener。监听成功和失败的处理结果,根据具体的结果对消息进行重新发送或记录日志处理等后续操作。

  2. Return消息机制
      我们的消息生产者,通过指定一个Exchange和Routing,把消息送达到某一个队列中去,然后我们的消费者监听队列进行消息的消费处理操作。

MQ常见问题

  1. 消息队列的有点
      (1)异步处理:相对于传统的串行方式,提高了系统吞吐量。
      (2)应用解耦:系统间的消息提供者与消息消费者解耦。
      (3)流量削峰:可以通过消息队列长度控制请求量。可以缓解短时间内的高并发请求。

  2. 消息队列有哪些缺点
      (1)系统复杂性提高:引入消息队里,需要考虑很多方面的问题。比如:一致性问题如何保证消息不被重复消费等。
      (2)一致性问题:生产者A系统处理完直接返回成功,调用者都以为这个请求是成功的了。但是问题是,BCD三个消费者系统那里可能会有某一个操作失败。这就导致数据不一致了。

  3. 你们公司生产环境用的是什么消息中间件
      我们公司使用的是RabbitMQ。
      如何选型:
      ActiveMQ过去很多公司使用,功能很强大,但是ActiveMQ无法支持互联网公司的高并发,高负载以及高吞吐量的复杂场景。在国内互联网公司落地较少。没有经过大规范的吞吐量场景的验证,社区也不是很活跃了
      RabbitMQ,开源的,社区活跃度高时效性微秒级别的,低延迟。它可以支撑高并发,高吞吐,性能很高。同时又非常完善边界的后台管理界面可以使用。它还支持集群化,高可用部署架构,消息高可靠支持,功能较为完善。而且经过调研,国内各大互联网公司落地大规范RabbitMQ集群支撑自身业务的case较多。但是它也有一些缺点,比如,它是用elang语言编写的,难以分析里面的源码,也难以进行深层次的源码定制和改造。
      RocketMQ,是阿里开源的,经过阿里的双十一考验,性能卓越。

  4. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?
    在这里插入图片描述

  5. MQ 有哪些常见问题?如何解决这些问题?
      (1)消息的顺序问题
      消息的顺序问题是指可以按照消息的发送顺序来消费。比如A生产了消息M1,M2。消费者B,C分别拿到了M1和M2,如何保证M1比M2优先执行?
      解决方案:生产者消费者一对一的关系。
      (2)消息的重复问题
      造成消息重复的根本原因是:网络不可达。
      所以要解决这个问题就是要解决如何消费端收到两条一样的消息,应该怎么处理?
      消费端处理消息的业务逻辑要保持幂等性。只要保持幂等性,不管来多少条重复消息,最终结果都一样。保证消息的唯一编号且保证消息处理成功与去重表的日志同时出现。利用一张日志表来记录已经处理成功的消息的ID,如果有新的消息ID已经在日志表中,那就不再处理这条消息。

  6. 如何保证消息不被重复消费?或者说,如何保证消息消费时的幂等性?
      正常情况下,消费者消费完消息的时候,会发送一个确认消息给消息队列,消息队列知道该消息被消费了,就会将消息从消息队列中删除。
      但是因为网络传输等故障,确认信息没有传送到消息队列,导致消息队列不知道自己易筋经消费过该消息了,再次将消息分发给其他消费者。
      解决方案:
      保证消息的唯一性,就算是多次传输,不要让消费的多次消费带来影响。保证消息幂等性。
      比如:在写入消息队列的数据做唯一标识,消费消费时,根据唯一标识判断是否消费过。
      假设你有两个系统,消费一条消息就往数据库里插入一条记录。要是你一个消息重复消费两次,你不就插入了两条,这数据不就错了?但是你要是消费到第二次的时候,自己判断一下是否已经消费过了,若是就直接扔了。这样就保留了一条数据,从而保证了数据的正确性。

  7. 如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息?
    发送方确认模式
      将信道设置成confirm模式,则所有在信道撒花姑娘发送的消息都会指派一个唯一的ID。
      一旦消息被投递到目的队列后,或者消息被写入磁盘后,信道会发送一个确认给生产者(包含唯一消息ID)。
      如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条nack消息。
      发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息。

  接收方确认模式
  消费者接收每一条消息后都必须进行确认。只有消费者确认了消息,RabbitMQ才能安全的把消息删除。
  这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长的时候来处理消息。保证数据的最终一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值