rabbitmq学习笔记

基础概念

基础架构图:
rabbitmq学习笔记_第1张图片
borker: 负责接收和分发消息的应用,一个RabbitMQ Server 就是 Message Broker
Virutal Host: 出于多租户和安全因素设计的,把AMQP的基本组件拆分到一个虚拟的分组中,有点类似于一个数据库连接中拥有多个数据库。当多个用户连接到同一个RabbitMq Server时,可以划分出来多个Virutal Host,每个用户可以在自己的Virutal Host中建立Exchange和Queue。
Connection: Producer 和 Consumer 和 Broker 的 Tcp 连接。
Channel: 如果每一次访问 RabbitMQ Server 都建立一次Tcp连接,那么这是十分耗费性能的。Channel 是 Connection 内部建立的逻辑,如果应用程序支持多线程,通常每个 Thread 都会建立一个 Channel 进行通讯,AMQP中包含了 channel id 帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel可以帮助操作系统减少建立TCP的开销。
Exchange: 消息到达 Broker 的第一站,消息到达后,会根据不同的规则,转发至不同的 Queue 中,常见的模式有:direct,topic,fanout。
Queue: Exchange将消息转发至 Queue 后,consumer从 Queue 中将消息取走。
Binding: Exchange 和 Queue 中的虚拟连接,binding 定义了一些转发规则,帮助 Exchange 分发到 Queue中。

RabbitMQ的工作模式

1. 简单模式
在这里插入图片描述
producer发送消息不指定Exchange,使用默认的Exchange,直接将消息放入指定的队列,consumer直接从监听的队列中取出消息消费。

2.Work queues 工作队列模式(竞争模式)
rabbitmq学习笔记_第2张图片
与简单模式相比,唯一不同的就是会有多个consumer同时监听一个 Queue,一条Message只会被一个Consumer取出消费。
如何决定一条Message会被哪个Consumer消费:
a. 公平模式,轮询分发;
b. 非公平模式,依照Consumer的消费能力进行分发,谁先消费完Message就分发给谁。

3.Publish / Subscribe(发布 / 订阅模式)
rabbitmq学习笔记_第3张图片
与前两种模式相比,多了一个Exchange。
需要注意的是,Exchange 不存储消息,如果没有 Queue 与 Exchange 绑定,那么这条消息就会丢失!

Producer将Message发送到 Exchange,Exchange 将 Message发送到所有的 Queue 中,每个 Queue 都会收到 Message。

4.Routing 模式(路由模式)
rabbitmq学习笔记_第4张图片
Exchange 将 Message 发送到 Queue 时,会按照 Binding 指定的Routing key转发至不同的 Queue 中。与 发布 / 订阅模式 相比,Message 不会被转发至所有的 Queue,而是通过一定的规则进行转发。
需要注意的是,一条Message可以被多个Queue接收。

5.Topic 模式(主题模式)
rabbitmq学习笔记_第5张图片
与 Routing 模式 唯一不同的是匹配时的 Routing key 是通配符模式。
Routing key 一般是一个在单词之间都是以 “.” 分割。
匹配规则:
a. # 匹配一个或多个词
b. * 匹配一个词

消息的可靠性投递

为了杜绝消息的生产者投递消息失败或者消失丢失的场景,RabbitMq提供了两种模式保证投递消息的可靠性。
首先看看RabbitMq整个消息的投递路径:
producer -> broker -> exchange -> queue -> consumer

  • Confirm 确认模式: Message到达 Broker 后会返回一个 confirmCallBack。
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack){
                System.out.println("消息接收成功");
            }else {
                System.out.println("消息接收失败,cause: " + cause);
            }
        });
  • Reruen 退回模式: 消息到达Exchange,找不到对应的Routing key进行消息转发,则会返回一个returnCallBack。
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            System.out.println("return 执行了....");

            System.out.println("message:"+message);
            System.out.println("replyCode:"+replyCode);
            System.out.println("replyText:"+replyText);
            System.out.println("exchange:"+exchange);
            System.out.println("routingKey:"+routingKey);
        });

利用这两个模式,可以确保消息的可靠性投递。

消息的可靠消费

为了确保消息在consumer消费时消息不会因为消费异常而丢失,RabbitMq提供的 consumer ack的机制。
一般情况下,consumer在获取到消息后,不先确认消息已被消费,而是放到业务代码的最后面,业务代码结束 ,调用 channel.basicAck(), 确认消息已被成功消费;如果业务代码异常,则调用 channel.basicNack(),让消息重新回到队列中。

消息的可靠性总结

  1. 持久化(包含 Exchange, Queue , Message)
  2. product的Confirm和Return
  3. consumer的手动确认ack
  4. broker的高可用

死信队列

死信队列有个重要的概念:DLX(Dead Letter Exchange),死信交换机。
rabbitmq学习笔记_第6张图片
死信交换机本质上就是一个交换机,它的作用是当消息成为Dead Message后,被重新发送到另外一个Exchange中,这个Exchange就是DLX。DLX再将Dead Message发到对于Queue中,供处理死信的Consumer消费。

消息成为Dead Message的三种情况:

  1. 队列消息超过限制长度;
  2. 消费者拒绝消费消息:channel.basicNack(),并且不将消息放回队列中:requeue: false;
  3. 原队列有消息过期设置,消息过指定时间后未被消费。

你可能感兴趣的:(java-rabbitmq,rabbitmq,学习)