RabbitMQ复习

消息中间件的作用:(1)异步处理 (2)应用解耦 (3)流量削峰

消息中间件的缺点:引入了新的东西,也就增加了新的故障点。比如消息中间件挂了,影响系统的可用性。

两种框架:JMS和AMQP

最大的区别是JMS是是java api,对跨平台的支持较差,但在纯java技术栈内首选。

AMQP是跨平台的,序列化方式选json,不管你是java,php,C/C++,python,都能处理

RabbitMQ实现的事AMQP协议

核心概念

Message 消息。消息不具名,由消息头和消息体组成。消息头包括routing-key(路由键)等,消息体即业务消息

Publisher 生产者,发送消息的一方

Exchange 交换机,类似网络中的交换机,通过一些规则将消息路由到指定的地方,有direct、fanout、topic、header四种类型

Queue 消息队列 用来保存消息直至被消费者消费,是消息的容器。一个消息可以被发送到一个或多个消息队列

Binding 绑定关系 定义Exchange和Queue(也可能还是Exchange )之间的路由关系。

Consumer 消费者,即从队列中取出消息进行处理的一方

Connection 网络连接 比如一个TCP长连接

Channel TCP长连接建立后再里面开辟虚拟信道,通过虚拟信道传递消息,避免频繁创建连接

Virtual Host 表示一批交换机、队列、绑定关系,一个RabbitMQ的server中可以有多个Virtual Host,它们之间是相互隔离的。默认为/

Broker 表示消息队列服务器实体

Exchange类型:

Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct、 fanout、topic、headers 。headers 匹配 AMQP 消息的 header 而不是路由键, headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了,所以直接 看另外三种类型

Direct Exchange:消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器 就将消息发到对应的队列中。路由键与队 列名完全匹配,如果一个队列绑定到交换 机要求路由键为“dog”,则只转发 routing key 标记为“dog”的消息,不会转发 “dog.puppy”,也不会转发“dog.guard” 等等。它是完全匹配、单播的模式。

Fanout Exchange:每个发到 fanout 类型交换器的消息都 会分到所有绑定的队列上去。fanout 交 换器不处理路由键,只是简单的将队列 绑定到交换器上,每个发送到交换器的 消息都会被转发到与该交换器绑定的所 有队列上。很像子网广播,每台子网内 的主机都获得了一份复制的消息。 fanout 类型转发消息是最快的

Topic Exchange:topic 交换器通过模式匹配分配消息的 路由键属性,将路由键和某个模式进行 匹配,此时队列需要绑定到一个模式上。 它将路由键和绑定键的字符串切分成单 词,这些单词之间用点隔开。它同样也 会识别两个通配符:符号“#”和符号 “*”。#匹配0个或多个单词,*匹配一 个单词。

如何保证消息的可靠传递:

(1)从生产者到broker :消息成功到达会调用confirmCallback 确认模式

(2)从Exchange到Queue:returnCallback 未投递到 queue,会调用returnCallBack()方法

(3)消费端开始手动确认

增加配置:spring.rabbitmq.listener.simple.acknowledge-mode: manual  #如果是auto则自动确认

代码中手动确认。成功消费则basicAck,失败则basicReject

basicReject和basicNack的区别:‌

basicReject:

  • 只能拒绝单条消息。‌
  • 当使用basicReject方法拒绝消息时,‌可以通过设置第二个参数requeue来决定是否将消息重新放入队列。‌如果设置为true,‌则消息会被重新放入队列;‌如果设置为false,‌则消息可能会被丢弃或发送到私信路由。

basicNack:

  • 可以批量拒绝多条消息。‌
  • basicNack方法允许您不确认多条消息,‌通过设置第二个参数multiple来决定是否应用于多条消息,‌而第三个参数requeue则决定是否将消息重新放入队列。‌
  • basicReject相比,‌basicNack提供了更灵活的方式来处理多条消息,‌尤其是在需要批量处理或拒绝消息时
  • 死信Exchange。‌

multiple为true表示批量确认,即确认此消息的tag号及其之前的所有消息,有的想TCP通信中的确认。如果multiple为false,则表示只确认当前这一条消息

同时为了保证机器断点消息也不丢失,queue 和 exchange 应设置为durable,message 具有 persistent 属性。

死信:因为队列装不下了、超时、或者手动reject并且requeue设置为false,都会导致消息变成死信。队列如果没有设置对应的死信路由,则直接丢弃;否则就发给死信路由。

死信路由Dead Letter Exchange其实就是一种普通的exchange,和创建其他 exchange没有两样。只是在某一个设置Dead Letter Exchange的队列中有 消息过期了,会自动触发消息的转发,发送到Dead Letter Exchange中去。

常见问题

一、消息丢失

为了保证可靠传输,除了上述的消息确认机制外,还需做好容错方法(try-catch),因为网络波动等原因直接在发送端就没能发送消息是常有的情况,这时候需要有重试机制。如果网络长时间不通,可以将发送失败的消息直接写入数据库,然后定期扫描对应表进行处理。

二、消息重复

(1)消费接口做好幂等性

(2)防重表:比如要发一个订单创建消息,发送前先往一个防重表中插入订单编号,并且表约束设置了订单编号为唯一索引,如果插入成功,则发送消息;如果插入失败,捕获唯一索引异常,直接返回成功。当然这里要考虑如果插入了防重表,但消息没发送成功呢?所以一定要加上事务,并且在没发送成功时确保抛出异常,以保证数据库回滚。

(3)消息头中有个redelivered字段,可以获取来辅助判断

三、消息积压
(1)上线更多的消息者

(2)先取出来放到数据库中,后面慢慢消费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值