RabbitMQ学习记录

基本点

RabbitMQ是一种消息队列。用于解决如下问题:

  1. 模块与模块之间的耦合度过高问题。
  2. 通讯成本过高问题

它严格遵循AMQP协议。

其简单架构由如下
在这里插入图片描述

  • 生产者:发布消息到exchange
  • 交换机(exchange):和生产者建立连接并接受消息
  • 路由(route):以一定的策略将exchange中的消息发送到queue
  • 队列(queue):exchange会将消息根据路由策略分到指定的queue中,并与消费者交互
  • 消费者:消费消息

完整架构(图源于网络资料截取)
在这里插入图片描述

一个队列中的消息,只会被一个消费者消费一次。
消息不会被重复消费。

安装

利用docker安装rabbitmq非常简单

version: "3.1"
services: 
  rabbitmq: 
    image: daocloud.io/library/rabbitmq:management
    restart: always
    ports:
      - 5672:5672
      - 15672:15672
    volumes: 
      - ./data:/var/lib/rabbitmq

5672为rabbitmq默认的服务端口号
15672为其图形化管理界面的端口号。

通讯方式

1. hello world型

在这里插入图片描述
一个生产者,一个默认交换机,一个队列,一个消费者。

2. work queues型

在这里插入图片描述
一个生产者,一个默认交换机,一个队列,两个消费者

3.publish/subscribe 型

在这里插入图片描述
一个生产者 一个自定义交换机,多个队列,多个消费者

exchange的类型

  • fanout:pubsub 型指定
  • direct: routing 型指定
  • topic : topic类型指定

4. routing 型

在这里插入图片描述
一个生产者,一个交换机,多个队列,多个消费者

消息通过routing-key进行绑定

exchange类型为direct

5. topic 型

在这里插入图片描述

一个生产者,一个交换机,多个队列,多个消费者

exchange类型为topic

绑定配对方式

* 为占位符
# 为通配符

举例子:
一个消息现在有 年龄,性别,职位 三种类型
假定有
 18,男,教师
20,男,程序员
19, 女,明星

*.男.* 说明只要是男性都可以接收
19.# 说明只要是19岁都可以接收 

一个exchange可以绑定多个队列,并且一个队列可以被多次绑定

常见问题

为什么要手动ACK

因为消息只会被消费一次。
如果在程序中,你刚接到消息,然后就自动ack了,后续程序中出现了错误,逻辑没有成果走完,那这条消息相当于就没有作用。
开启手动ack,在代码成功执行后,再ack,可以保证消息的有效利用。

rabbitMQ的可靠性怎么实现

情况一

消息到达了mq,但mq宕机了,消息会丢失吗?

  • 消息不会丢失,因为队列有持久化机制。
情况二

消费者受到消息,但执行一半,消费者出现问题,消息会丢失吗?

  • 不会,因为可以手动ack,确保消息一定会被有效使用
情况三

生产者发送消息时,没有发送到MQ,这时候怎么办?

  • rabbitMQ提供了事务机制和confirm机制
  • 事务机制可以保证消息的传递,可以通过回滚去记录日志,然后之后定时再发送,但事务操作效率很低,所以不推荐使用
  • confirm机制有三种形式:1. 普通confirm 2. 批量confirm 3. 异步confirm
  • 即exchange收到消息后会进行回调。
  • 所以confirm机制是保证了消息从生产者到exchange的过程中不出现错误。
情况四

如果消息从exchange发送到queue失败,怎么办?

  • return机制
  • return机制保证了消息从exchange发送到queue的准确性,如果期间出现问题,程序中可以进行回调提示。

如何避免消息的重复消费

假定现在,有两个服务,服务A消费了消息,但没有ack;然后服务B又消费了此消息,这时候就出现了消息重复消费的情况,怎么解决?

  • 用redis解决
  • 给消息加上一个id,存入redis。在消息消费之前,将id放入redis中,并将其值标识为0,表达正在执行,消息消费成功后,将值改变为1,标识消费成功。
  • 那么其他服务在消息时,先执行setnx,如果key存在,拿值,如果为0,什么都不做,因为其他服务可能正在消费;如果为1,则直接ack,并且删除此key。
  • 但可能服务中出现死锁情况,导致值一直为0;可以通过设置key的生存时间解决。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值