消息中间件学习笔记——RabbitMQ

Posted 虾米吃小鱼12138

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息中间件学习笔记——RabbitMQ相关的知识,希望对你有一定的参考价值。


一、消息中间件概述

  通过下图我们就可以很好理解消息中间件的概念。

二、消息中间件(MQ)的优劣

(1).MQ的优势

  1. 应用解耦

  2. 任务异步处理

  3. 削峰填谷

(2).MQ的劣势

系统可用性降低

  系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?
  我们可以建立MQ的集群来提高MQ的高可用。

系统复杂度提高

  MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?
  一旦消费者处理完请求会向MQ传递一个ack(类似心跳),以此来保证消息没有被重复消费。MQ以队列形式进行消息传输,以此来保证消息传递的顺序性。至于如何处理信息丢失的情况,我们以rabbitMQ为例,分为以下三种情况进行讨论:

  • 生产者弄丢了数据
      可以开启confirm模式。在生产者哪里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如何写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。
  • rabbitmq自己弄丢了数据
      设置消息持久化到磁盘。设置持久化有两个步骤:
    ①创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里面的数据。
    ②发送消息的时候讲消息的deliveryMode设置为2,这样消息就会被设为持久化方式,此时rabbitmq就会将消息持久化到磁盘上。
    必须要同时开启这两个才可以。
      而且持久化可以跟生产的confirm机制配合起来,只有消息持久化到了磁盘之后,才会通知生产者ack,这样就算是在持久化之前rabbitmq挂了,数据丢了,生产者收不到ack回调也会进行消息重发。
  • 消费者弄丢了数据
      使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。

一致性问题

  A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息,如果 B 系统、C 系统处理成功,D 系统处理失败。如何保证消息数据处理的一致性?
  D系统处理失败,意味着没有将ack返回给MQ,MQ会定时重复发送未收到ack的消息,为了保证数据不出现重复的情况,即幂等性,对于每条消息,MQ内部生成一个全局唯一、与业务无关的消息ID:inner-msg-id。当MQ-server接收到消息时,先根据inner-msg-id判断消息是否重复发送,再决定是否将消息落地到DB中。这样,有了这个inner-msg-id作为去重的依据就能保证一条消息只能一次落地到DB。

三、常见的MQ产品

四、RabbitMQ中的概念

RabbitMQ 中的相关概念:

  • Broker:接收和分发消息的应用,RabbitMQ Server就是 Message BrokerVirtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个vhost,每个用户在自己的 vhost 创建 exchange/queue 等
  • Connection:publisher/consumer 和 broker 之间的 TCP 连接
  • Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCPConnection的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的 channel 进行通讯,AMQP method 包含
    了channel id 帮助客户端和message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销
  • Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)
  • Queue:消息最终被送到这里等待 consumer 取走
  • Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据

五、如何实现RabbitMQ的延迟对列

延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。

需求:

  1. 下单后,30分钟未支付,取消订单,回滚库存。
  2. 新用户注册成功7天后,发送短信问候。

实现方式:

  1. 定时器(性能损耗过大,不考虑)
  2. 延迟队列

以上是关于消息中间件学习笔记——RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

分布式消息中间件之RabbitMQ学习笔记[一]

分布式消息中间件之RabbitMQ学习笔记[一]

RabbitMQ学习笔记

RabbitMQ学习笔记

springboot学习笔记-6 springboot整合RabbitMQ

学习笔记《RabbitMQ实战指南》笔记