rabbitmq:3.9.2
spring-boot-starter-amqp:2.3.0.RELEASE
架构
-
Producer 生产者
- 消息成功发送到交换机, 会触发回调事件ConfirmCallback(需要配置)
- 消息不能被交换机转发到队列中时, 会触发回调事件ReturnCallback(需要配置)
-
Exchange 交换器
-
Fanout
把所有发送到该交换器的消息路由到所有与该交换器绑定的消息队列中. 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的
-
Direct 把消息路由到BingingKey 和RoutingKey 完全匹配的队列中
会把消息路由到BindingKey 和RoutingKey 完全匹配的队列中. 如果一个队列绑定到该交换机上要求路由键"dog",则只有被标记为"dog"的消息才被转发,不会转发dog.puppy,也不会转发dog.guard,只会转发dog, 多个队列可以使用一个键
-
Topic
Topic 类型的交换器在 direct 匹配规则上进行了扩展. 不是进行完全匹配. 而是进行模糊匹配. 匹配规则如下: BindingKey和RoutingKey一样都是由".“分隔的字符串; BindingKey中可以存在两种特殊字符”*" 和 “#”, 用于模糊匹配, 其中"*"用于匹配一个单词, “#“用于匹配多个单词(可以是0个), 因此"audit.#“能够匹配到"audit.irs.corporate”,但是"audit.*” 只会匹配到"audit.irs”
-
Headers
Handers 类型的交换器不是根据路由匹配规则来的,而是根据消息中的 headers 属性进行匹配的。在绑定队列和交换器时指定一组键值对,当发送的消息到交换器时,RabbitMQ会获取到该消息的headers,对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果匹配,消息就会路由到该队列。headers类型的交换器性能很差,不实用
-
-
Bindings 绑定(匹配)器 把exchange和queue按照路由规则绑定(匹配)起来
- BindingKey 队列绑定的key, 初始化时绑定
- RoutingKey 消息携带的
-
Queues 队列
-
Consumer 消费者
其他概念
- Broker 提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输
- Vhost 虚拟主机,一个broker里可以有多个vhost, 用作不同用户的权限分离
- Channel 消息通道, 可以理解为建立在生产者/消费者和RabbitMQ服务器之间的TCP连接上的虚拟连接,一个TCP连接上可以建立多个Channel
特性
消息确认
-
自动确认
- RabbitMQ成功将消息发出 (即消息成功写入TCP Socket) 中立即认为本次投递已经被正确处理,不管消费者端是否成功处理本次投递
-
手动确认
- basic.ack 肯定确认
- basic.nack 用于否定确认 (注意: 这是AMQP 0-9-1的RabbitMQ扩展)
- basic.reject用于否定确认, 但与basic.nack相比有一个限制: 一次只能拒绝单条消息
- 使用手动确认需要对客户端进行配置.
- 第2, 3种, 都可以通过设置参数, 将消息重新放回到队列中
TTL
- 时间范围
0 <= n <= 2^32-1
ms, 约 49 天
死信队列
-
可以和TTL配合实现延时队列 将消息设置ttl, 发送到死信队列中 (不设置消费者处理), 等待过期被转发到延时队列
-
但该延时队列有缺陷, 若发送两条延时消息, 第一条延时10s, 第二条延时5秒, 若第一条先入队列, 则只有当第一条消息过期发送到死信队列后, 第二条消息才能被处理, 即过期是阻塞的. 但可以通过安装
rabbitmq_delayed_message_exchange
插件解决, https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases终端启用插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
代码中配置
/** * * @author https://www.skypyb.com/ */ @Configuration public class RabbitBindConfig { public final static String SKYPYB_DELAY_EXCHANGE = "skypyb-delay-exchange"; public final static String SKYPYB_DELAY_QUEUE = "skypyb-delay-queue"; public final static String SKYPYB_DELAY_KEY = "skypyb.key.delay"; @Bean public CustomExchange delayExchange() { Map<String, Object> args = new HashMap<>(); args.pu