本 wiki 基于
rabbitmq 3.7.16
和springboot 2.x
1 | <dependencies> |
认识 RabbitMQ
MQ
消息队列(Message Queue)
: 一种应用对应用的通讯方法,应用间通过读写队列中的消息就可以完成通信,不需直接通信。从存储消息的角度来看,消息队列也可以理解为消息容器。
MQ 的作用 : 异步
, 削峰
, 解耦
。
AMQP & JMS
MQ 实现方式 | 说明 |
---|---|
AMQP |
应用层协议,不受开发语言等限制。消息模型更加丰富。 |
JMS |
Java Message Service 实际指 JMS API ,只能使用 Java 语言。规定了两种消息模型。 |
RabbitMQ
RabbitMq
是开源的,基于 AMQP 的跨平台跨语言的消息队列。
常见 MQ 产品 | 说明 |
---|---|
ActiveMQ |
基于 JMS。 |
RabbitMQ |
基于AMQP协议,基于 erlang 语言开发,稳定性好。 |
RocketMQ |
基于JMS,阿里巴巴产品,目前交由Apache基金会。 |
Kafka |
分布式消息系统,高吞吐量。 |
使用 RabbitMQ
常用消息模型
ConnectionUtil.java
1 | package tk.gushizone.rabbitmq.util; |
QueueConst.java
1 | package tk.gushizone.rabbitmq.constant; |
ExchangeConst.java
1 | package tk.gushizone.rabbitmq.constant; |
Simple
Simple消息模型
是最简单的生产消费模型。
*Producer.java
1 | package tk.gushizone.rabbitmq.sample.simple; |
1 | Producer sent : [Hello World!] |
*Consumer.java
ACK (Acknowledge character)
: 确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。
自动 ACK
1 | package tk.gushizone.rabbitmq.sample.simple; |
1 | Consumer received : [Hello World!] |
手动 ACK
1 | package tk.gushizone.rabbitmq.sample.simple; |
1 | Consumer received : [Hello World!] |
Work
Work消息模型
与 Simple
仅仅分别是单体和集群的区别,更强调负载均衡,能者多劳。
*Producer.java
1 | package tk.gushizone.rabbitmq.sample.work; |
1 | Producer sent [task .. 0] |
Recv.java
1 | package tk.gushizone.rabbitmq.sample.work; |
1 | Consumer1 received : [task .. 0] |
Recv2.java
1 | package tk.gushizone.rabbitmq.sample.work; |
1 | Producer sent [task .. 0] |
Fanout
Fanout消息模型
又称之为广播模型, produce
可以通过 交换机(exchange)
把消息发给多个队列和对应 consumer
。
Producer.java
1 | package tk.gushizone.rabbitmq.sample.fanout; |
1 | Producer sent [Hello World] |
Recv.java
1 | package tk.gushizone.rabbitmq.sample.fanout; |
1 | Consumer1 received [Hello World] |
Recv2.java
1 | package tk.gushizone.rabbitmq.sample.fanout; |
1 | Consumer2 received [Hello World] |
Direct
Direct消息模型
又称之为 路由模型,其是 Fanout
的增强,通过 routingkey
,交换机可以有选择的将消息转发给对应的队列。
Producer.java
1 | package tk.gushizone.rabbitmq.sample.direct; |
1 | Producer sent [商品删除, id = 1001] |
Recv.java
1 | package tk.gushizone.rabbitmq.sample.direct; |
1 | Consumer1 received [商品删除, id = 1001] |
Recv2.java
1 | package tk.gushizone.rabbitmq.sample.direct; |
1 | Consumer2 received [商品删除, id = 1001] |
Topic
Topic消息模型
是 Direct
的增强版, 让 routingkey
支持通配符。
*
:一个词。#
:多个词。
持久化
- 队列 | 交换机持久化:
durable
。 - 消息持久化:
MessageProperties.PERSISTENT_TEXT_PLAIN
。
Producer.java
1 | package tk.gushizone.rabbitmq.sample.topic; |
1 | Producer sent [新增商品 : id = 1001] |
Recv.java
1 | package tk.gushizone.rabbitmq.sample.topic; |
1 |
Recv2.java
1 | package tk.gushizone.rabbitmq.sample.topic; |
1 | Consumer2 received [新增商品 : id = 1001] |
Spring AMQP
spring amqp
是对AMQP协议的抽象实现,而 spring-rabbit
是对协议的具体实现,也是目前的唯一实现。
核心配置
pom.xml
1 | <dependencies> |
application.yml
1 | spring: |
@RabbitListener
@RabbitListener |
说明 |
---|---|
bingdings |
指定绑定关系,可以有多个。值是@QueueBinding 的数组。 |
@QueueBinding |
说明 |
---|---|
value |
这个消费者关联的队列,使用 @Queue 指定队列。 |
exchange |
队列所绑定的交换机,使用 @Exchange 指定交换机。 |
key |
即 RoutingKey。 |
1 | package tk.gushizone.rabbitmq.spring; |
1 | 接收到消息:[hello, Spring boot amqp] |
AmqpTemplate
AmqpTemplate
可以十分方便的发送消息。
1 | package tk.gushizone.rabbitmq.test.spring; |
附录
[Mac] 安装 RabbitMQ
仅介绍基于
hombrew
的安装方法。
安装并启动后,使用默认用户 guest/guest
,访问 http://localhost:15672/ 。
1 | 安装 rabbitmq |
常见问题处理
常见问题 | 解决方式 | ||
---|---|---|---|
消息丢失 |
1)手动 ACK 。2)持久化:消息 \ | 队列 \ | 交换机。 |
消息重复 |
1)业务幂等。2)使消息拥有唯一不变 key,redis 记录。 | ||
消息顺序 |
主动分配队列,一个队列一个消费者。 |