安装配置
📌注意Erlang与MQ的版本对应,可在官网版本页查看
- 安装Erlang
- 配置环境变量,复制对应bin路径
安装目录\Erlang OTP\bin
将此路径添加到系统环境变量的PATH字段下,之后保存后,打开命令控制台,输入erl -v
查看是否可以正常显示版本号 - 安装RabbitMQ
- 安装结束后进入对应目录的sbin文件夹,在此处打开命令控制台,输入
rabbitmq-plugins enable rabbitmq_management
待安装完成,
右键“此电脑”,选择管理,打开windows的服务界面,启动rabbitMQ服务 - 浏览器输入MQ的控制台地址,输入帐号密码 guest / guest 即可登录查看
基础概念
📌RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议
在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写
的,并且RabbitMQ是基于AMQP1协议的。
server | 又称Broker,接受客户端的连接,实现AMQP实体服务 |
---|---|
Connection | 连接,应用程序与Broker的网络连接 |
Channel | 网络通道,几乎所有的操作都在Channel中进行,Channel是进行消息读取的通道。客户端可建立多个Channel,每个Channel代表一个会话任务。 |
Message | 消息,服务器和应用程序之间传送的数据,由Properties和Body组成。Properties可以对消息进行修饰,比如消息的优先级、延迟等高级特效,Body则就是消息体内容 |
Virtual host | 虚拟地址,用户进行逻辑隔离,最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,同一个Virtual Host里面不能有相同名称的Exchange和Queue |
Exchange | 交换机,接收消息,根据路由键转发消息到绑定的队列 |
Binding | Exchange和Queue之间的虚拟连接,binding中可以包含routing key |
Routing key | 一个路由规则,虚拟机可用它来确定如何路由一个特定消息 |
Queue | 也称作MessageQueue,消息队列,保存消息并将它们转发给消费者 |
死信队列是什么?
死信队列也是一个消息队列,它是用来存放那些没有成功消费的消息的,通常可以用来作为消息重试,如果队列没有配置死信队列,则消息一旦成为“死信”,便会直接丢弃
死信队列并不是什么特殊的队列,只不过是绑定在死信交换机上的队列。死信交换机也不是什么特殊的交换机,只不过是用来接收死信的交换机,所以可以为任何类型(Direct、Fanout、Topic
)。一般来说,会为每个业务队列分配一个独有的路由 key
,并对应的配置一个死信队列进行监听,也就是说,一般会为 每个重要的业务队列配置一个死信队列
什么情况下消息会进入死信队列?
- 消息被消费者拒绝且告知MQ将该消息放入死信队列
a. 消费者回了一个Nack,而且第三个参数为false,channel.basicNack(deliveryTag, false, false)
b. 消费者回了一个Reject,且第二个参数为false,channel.basicReject(deliveryTag, false)
- 消息在队列中的存活时间过期,即消息可以设置TTL2,TTL超时就会被放进死信队列。
- 队列设置了
x-max-length
最大消息数量且当前队列中的消息已经达到了这个数量,再次投递,消息将被挤掉,被挤掉的消息会路由进死信队列 - 当重复投递次数达到了设置的消费者设置了自动 ACK,当重复投递次数达到了设置的最大 retry 次数之后,消息也会投递到死信队列,但是内部的原理还是调用了basicNack()或basicReject()
#开启rabbitmq的生产端重试机制,默认是false,默认重试 3 次
spring.rabbitmq.template.retry.enabled=true
#开启rabbitmq的消费端重试机制,默认是false,默认重试 3 次
spring.rabbitmq.listener.simple.retry.enabled=true
#设置重试的次数
spring.rabbitmq.listener.simple.retry.max-attempts=5
什么是延时队列?
延时队列就是用来存放需要在指定时间被处理的消息队列,通常可以用来处理一些具有过期性操作的业务,比如十分钟内未支付则取消订单
本质上就是TTL机制加上死信队列,如消息设置TTL为30分钟,并为其设置一个死信队列,消息到期后就进入死信队列处理了
如何尽量避免消息丢失?
- 消息发送+回调确认、开启事务
- 开启spring的重试机制(retry)
如何信息消费的幂等性
- 给每条消息确定唯一消息ID
更多做法参考保证接口幂等性
Direct、Fanout、Topic三种交换机的区别
-
Fanout Exchange交换机将会接到的消息路由到每一个与其绑定的队列中去
解释:通俗来讲就是有几个队列跟此交换机绑定,发送消息时就会发送给每一个绑定的队列 -
DirectExchange 会将接收到的信息根据规则路由制定的队列中去,因此也叫做路由模式(routes)
解释:在与此交换机绑定的基础上,根据routingKey的值来选择性的发送消息 -
TopicExchange与DirectExchange类似,区别在于routingKey必须是多个单词列表,并且以**
.
分割
解释:跟DirectExchange类似,只是还可以使用通配符#
或者*
**来代替String routingkey = “testTopic.#”; // 匹配多个词 String routingkey = “testTopic.*”; // 匹配单个词