RabbitMQ入门
RabbitMQ
介绍#
MQ全称为Message Queue,即消息队列。“消息队列”是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都 是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。
优势
- 应用解耦
在多个系统中加了一层,实现解耦
- 异步提速
将消息写入消息队列,消息队列统一给各个系统发送消息,实现异步提速
-
削峰填谷
MQ可以存储很多请求信息(相比于系统服务器),系统可以再去慢慢从MQ中拉取请求并消费 .
也就是说,将要处理的数据存储起来让系统在其可承受范围内来处理,提高了系统的稳定性
劣势
- 系统可用性降低
引入的依赖越多,可用性越差,一旦MQ宕机,会对业务造成影响,如何保证MQ高可用
- 系统复杂度提高
异步调用,如何保证消息没有被重复消费?怎么处理消息丢失?保证消息传递顺序
- 一致性问题
需要保证各系统间数据处理的一致性
与同类产品相比
吞吐量略低于RocketMQ和Kafka,性能极好,消息延迟低,社区活跃,管理界面丰富.
一个连接的channel对应一个交换机,交换机与队列绑定并通信,
安装&配置#
三个包
erlang语言包
erlang内存管理
rabbitmq安装包
erlang-22.0.7-1.el7.x86_64.rpm socat-1.7.3.2-2.el7.x86_64.rpm rabbitmq-server-3.7.18-1.el7.noarch.rpm
3个命令
rpm -ivh xxx1.rpm
rpm -ivh xxx2.rpm
......
配置#
安装完成后,默认会使用 /etc/rabbitmq/下的rabbitmq.config(需要自己上传)
cd /usr/share/doc/rabbitmq-server-3.7.18/
find / -name rabbitmq.config.example
- 安装vim
yum install -y vim
- 配置文件
注意:默认安装完成后配置文件模板在:/usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.examp1e目录中,需要将配置文件复制到/etc/rabbitmq/目录中, 并修改名称为rabbitmq.config cp /usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config #把原配置文件copy过去 ls /etc/rabbitmq/rabbitmq.config #查看配置文件位置 vim /etc/rabbitmq/rabbitmq.config #修改成自己的配置文件
- 打开web管理界面
修改用户配置权限(来宾账户) 添加了才能使用web管理界面
找到 %%{loopback_users, []}, 删除%%注释 改成 {loopback_users, []}
-
执行如下命令,启动rabbitmq中的插件管理
rabbitmq-plugins enable rabbitmq_management
查看服务状态
systemctl status rabbitmq-server
**启停RabbitMQ的服务 **
systemctl start rabbitmq-server # 启动 systemctl restart rabbitmq-server # 重启 systemctl stop rabbitmq-server # 关闭
出现:
[root@RabbitMQServer myFile]# systemctl status rabbitmq-server ● rabbitmq-server.service - RabbitMQ broker Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled) Active: inactive (dead) [root@RabbitMQServer myFile]# systemctl start rabbitmq-server [root@RabbitMQServer myFile]# systemctl status rabbitmq-server ● rabbitmq-server.service - RabbitMQ broker Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled) Active: active (running) since 一 2022-01-03 20:15:16 CST; 1min 40s ago Main PID: 1500 (beam.smp) Status: "Initialized" CGroup: /system.slice/rabbitmq-server.service ├─1500 /usr/lib64/erlang/erts-10.4.4/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 51... ├─1718 /usr/lib64/erlang/erts-10.4.4/bin/epmd -daemon ├─1862 erl_child_setup 32768 ├─1885 inet_gethost 4 └─1886 inet_gethost 4
关闭防火墙服务
systemctl status firewalld #查看 systemctl disable firewalld #禁用 Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. systemctl stop firewalld #关闭
help命令
rabbitmqctl help
进入管理界面
输入2个guest登录
工作模式#
简单直连#
工作队列#
其实就是直连队列,有多个消费者竞争消息
-
1个消息只能发给1个消费者,采用轮询方式平均发送
-
消费者处理完才会处理下条消息
流程
生产端:
1、声明队列
2、创建连接
3、创建通道
4、通道声明队列
5、制定消息
6、发送消息,使用默认交换机
消费端:
1、声明队列
2、创建连接
3、创建通道
4、通道声明队列
5、重写消息消费方法
6、执行消息方法
//给名字为spring_queue的队列发消息 rabbitTemplate.convertAndSend("","spring_queue","hello eazyZhiLian");
Pub/Sub订阅模式#
模式说明
P:生产者,发送消息给交换机
C: 消费者,消息接收者,一直等待消息到来
Quene: 消息队列,接收消息,缓存消息, 该模式中每个消费者监听自己的队列
Exchange: 交换机(X),一方面,接受生产者发送的消息,另一方面,知道如何处理消息,例如递给某个特别的队列、递给所有队列、或是将消息丢弃。如何操作取决于Exchange的类型。
常用类型有以下3种:
Fanout:广播,将消息交给所有绑定到交换机上的队列
当交换机为广播模式时,routingKey不需要
Direct: 定向,交给符合指定routing key的队列
Topic: 通配符,把消息交给符合routing pattern(路由模式)的队列 更加灵活 *代表一个单词,#号代表多个
Fanout#
广播模式 绑定交换机的队列都收到消息
Direct#
路由模式
- 队列与交换机的绑定,需要指定一个RoutingKey
- 消息的发送放在向Exchagne发送消息时,也必须指定消息的RoutingKey
- Exchange 不在把消息交给每一个绑定的队列,而是根据RoutingKey判断,只有队列的RoutingKey与消息的RoutingKey一致,才会收到消息。
Topic#
通配符模式
路由key中 #号代表多个单词 *号代表一个单词
springboot整合#
-
导入依赖
-
yml配置mq信息
-
生产端声明队列和交换机,绑定关系,通过rabbitTemplate发送消息
-
消费端@RabbitListener(queues = "xxx")监听队列
@Component public class RabbitMqListener { @RabbitListener(queues = "boot_queue") public void ListenerQueue(Message msg){ System.out.println("取出消息: "+new String(msg.getBody())); } }
高级特性
消息可靠性投递确认Confirm#
消息发送方希望杜绝任何消息丢失或者投递失败的场景.rabbitmq有2中方式控制消息的投递可靠性模式
整个消息的投递路径为
producer-->rabbitmq broker --> exchange --> queue --> consumer
- 消息从producer 到exchange会返回一个confirmCallback(无论投递成功与否 到了exchange,ack为true)
- exchange到queue失投递败 则会返回执行returnCallback
编码
在发送消息前定义回调函数 (实现匿名内部类的方法), 消息发送后会执行这个方法
消息发送是否成功会返回给boolean ack ,失败原因返回给cause correlationData是相关配置信息
消息可靠性投递回退Return#
发消息给Exchange,路由到Queue失败 才执行ReturnCallBack
-
默认是丢弃消息
-
spring: rabbitmq: publisher-confirms: true #开启回退模式
@Autowired private RabbitTemplate rabbitTemplate; { rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { @Override public void returnedMessage(Message message, int i, String s, String s1, String s2) { System.out.println(message+"投递到queue失败"); } }); rabbitTemplate.convertAndSend(RabbitMQConfig.Exchange_NAME, "boot.haha", "你好 boot mq"); }
-
开启回退模式
-
设置ReturnCallBack
-
设置Exchange处理消息的模式
- 如果消息没有路由到Queue,则丢弃(默认)
- 如果消息没有路由到Queue,则返回给消息发送方ReturnCallBack
Consumer Ack#
消费者收到消息的确认方式
三种方式<rabbit:listener-container acknowledge="xxx"
- 自动确认 acknowledge="none"
- 手动确认 acknowledge="manual"
- 根据异常情况确认 acknowledge="auto"
其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应message从RabbitMQ的消息缓存中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAckO, 手动签收,如果出现异常,则
调用channel.basicNack方法,设置requeue可让其自动重新发送消息。
编码
监听器实现ChannelAwareMessageListener
重写onMessage方法
如果消息处理成功,则调用channel的basicAck()签收
处理失败,则调用channel的basicNack()拒收,braoker重新发送consumer
消息可靠性总结#
- 持久化
- exchange要持久化
- queue要持久化
- message要持久化
- 生产方确认Confirm
- 消费方确认Ack
- Broker高可用
消费端限流#
- 确保ack机制为手动确认 acknowledge="manual"
- rabbit:listener-container配置属性 prefetch="100"
表示消费者每次从mq拉去100条消息,消费完毕(手动签收后)才继续拉去下100条
TTL#
介绍
-
Time to Live 存活时间
-
消息到达存活时间后,还未被消费,会自动清除
-
可以对消息设置,也可以对整个队列设置过期时间
编码
2种方式
第一种 对队列设置 1000 ms的TTL
第二种 对消息设置
如果都设置了,则优先按照短时间的TTL处理
消息过期,只在队列顶端被判断过期(移除)
死信队列#
当消息成为Dead message后 可以被重新发送到另一个交换机,这个交换机就是死信交换机
消息成为死信的情况
- 队列消息长度达到限制
- 消费者拒绝接受消息 basicNack() 并且requeue=false不把消息重新放入原队列
- 原队列存在消息过期设置,消息超时未被消费
声明2个正常队列和交换机 (其中一个作为死信队列) 并绑定
正常队列如何绑定死信交换机?
声明原队列时带上参数 x-dead-letter-exchange = exchange_dlx(交换机名)
x-dead-letter-routing-key = dlx.xxx(发送的路由key)
延迟队列#
消息进入队列后不会立即消费 只有到达指定时间后,才会被消费
利用TTL和死信队列实现,消费者监听死信队列
日志和监控#
默认日志存放路径: /var/log/rabbitmq/rabbit@xxx.log
消息追踪#
使用场景
- 削峰限流
- 异步处理
- 应用解耦
- 日志处理
- 消息通讯(聊天)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?