乐趣区

rabbitmq-入门到熟悉不敢说精通

rabbitmq 可使用的场景

  • 异步接口调用

有这样的一种场景,公司项目本来是通过 http 接口来调用第三方接口,但是这样带来了很多问题;我在实际项目中有碰到这样一种情况,由于对方服务不稳定,接口虽然调过去了,对方操作成功,但是由于网络原因或其它原因,未能返回成功的反馈,导致我方业务出错,这在量少的时候还可以通过人工处理解决,当量上来的时候,就是一场灾难。

  • 流量削锋
  • 日志处理

与 kafka 的优缺点

kafka 来说的话是高吞吐量,kafka 在每秒百万级别(一般用在设备上点等高频数据操作),完全分布式;而 rabbitmq 比较简单,遵循 amqp 协议,一般应用可以使用;不适合物联网数据上报

各组件说明

  • ConnectionFactory 连接工厂,用于设置连接相关信息,创建连接
  • Channel 信道,所有的发送消息,创建队列,创建交换机,接收消息都是通过它
  • Exchange 消息交换机,相当于 DispatchServlet
  • Queue 队列,存放消息的地方,只有这里可以存放消息
  • RoutingKey 路由键,设置消息路由,派发给哪个队列
  • BindingKey 绑定键,用于把队列绑定到交换机上,只有队列绑定到交换机上,消息才可以路由给队列

注意事项

  • 队列一经创建就不可以更改参数
  • 消息可以直接发到队列上,也可以由交换机转发

rabbitmq 的几种模式

这里我是学的这个视频,正好又找到对应的代码博客 视频地址

简单队列


解读:

  • 一个生产者
  • 一个消费者
  • 一个队列

代码: 简单队列

Work 模式


解读:

  • 一个队列
  • 两个消费者同时消费

代码 (轮询分发): 轮询分发
代码(公平分发): 也叫能者多劳 公平分发

订阅模式


解读:

  • 一个队列对应一个消费者
  • 多个队列,多个消费者
  • 消息是发到交换机上的
  • 消息是每个队列都转发全部消息

代码: 订阅模式

路由模式


解读:

  • 消息不再是全部转发,而是根据路由键来转发,做的全名称匹配
  • 队列可以和交换机绑定多个路由键

代码: 路由模式

主题模式


解读:

  • 这个可能和你原本理解的 kafka 的主题模式有区别,kafka 的主题模式应该是对应发布订阅模式
  • 这个相比较于路由模式来说是把全名称匹配换成了模式匹配,有了通配符

    • # 匹配所有
    • * 匹配一个 ~ 感觉有点反人类~

代码: 主题模式

如何保证消息的可靠性

生产端有两种方式来确保消息到达队列

  1. 事务机制(不建议,性能太低)

代码:事务机制

  1. confirm 机制

代码:confirm 同步模式,confirm 异步处理模式

消费者端有 ack 确认来确保可靠

// 将自动 ack 确认设置为 false,然后手动来确认已经收到消息并正确处理业务 
boolean autoAck=false;
channel.basicConsume("test",autoAck,defaultConsumer);

// 回应 rabbitmq 已经收到消息并处理
channel.basicAck(envelope.getDeliveryTag(),false);

上面的代码虽然能解决消息丢失的问题,但有一个弊端,就是当业务处理时间特别长的时候,rabbitmq 得不到回应,造成消息堆积。解决办法如下。

  1. 还是使用手动 ack
  2. 收到消息后,先把消息存入 rabbitmq 的一个未处理队列中
  3. 然后回执 ack
  4. 执行业务,业务处理完成后,发送二次确认到 rabbit 未处理队列, 消费掉未处理的消息

rabbitmq 本身可以做持久化来保证可靠性

// 设置方法在声明队列的第二个参数,是否持久化,设置为 true 即可
boolean durable = true;
channel.queueDeclare(QUEUE_NAME,durable,false,false,null);

死信队列和使用场景

什么是死信队列

  1. 一个消息被 Consumer 拒收了,并且 reject 方法的参数里 requeue 是 false。也就是说不会被再次放在队列里,被其他消费者使用。
  2. 上面的消息的 TTL 到了,消息过期了。
  3. 队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信路由上。

使用场景

  • 12306 的那种订单 30 分钟后超时,数据库中会一个订单状态,在 30 分钟后需要更新为已超时,使用传统方法时要么使用定时任务扫描订单,要么是保存一个 map 到内存,操作都很繁琐,这时候可以使用死信队列,设置队列消息的超时时间为 30 分钟,然后把消息通过死信交换机发送到特定队列中去,再有专门的程序更新单条记录为订单超时到数据库中。
  • 物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时,然后监听到命令超时再反馈给物联网系统。

使用 springboot 来调用 rabbitmq

  • 发送消息
  • 接收消息

一些小推广

Excel 通用导入导出,支持 Excel 公式
https://blog.csdn.net/sanri1993/article/details/100601578

使用模板代码,从数据库生成代码,及一些项目中经常可以用到的小工具
https://blog.csdn.net/sanri1993/article/details/98664034

感谢原作者, 文章引用

原作者的文章刚好能和视频对上,太感谢了,我只是帮原作者做了个文章排序而已;
引用你的文章希望不介意

https://blog.csdn.net/qq78442761/article/category/9040352
https://www.cnblogs.com/ssh-html/p/10542841.html

退出移动版