RabbitMQ

RabbitMQ初体验

🚧🚧🚧 暂待施工🚧🚧🚧

初识MQ

同步调用的优缺点

同步通讯与异步通讯

image-20240302142354005

​ 同步调用的时效性高

同步调用的问题

image-20240302143310461

image-20240302143340461

总结

同步调用的优点

  • 实时性好, 时效性高

同步调用的缺点

  • 耦合高, 系统需求更改导致维护, 更改困难
  • 性能吞吐量下降, 线性调用, 每次调用都要阻塞等待服务方响应, 导致性能下降
  • 资源浪费, 调用链每个服务都要等待响应过程, 无法释放请求占用的资源
  • 级联失败, 服务提供方出问题,所有调用方都会出问题, 多米诺骨牌

异步调用的优缺点

异步调用方案

优势一 服务解耦

image-20240302143821941

​ 采用发布订阅模式, 支付服务只负责发布事件Broker, 而其他服务只负责订阅相应的Broker

实现了, 服务调用方和提供方的解耦

image-20240302144400604

​ 假如, 需求发生变化, 需要在支付成功事件后添加其他服务, 只需要添加相应的服务, 并让该服务订阅相应的事件(支付成功事件)

image-20240302144600965

​ 假如, 需求又发生变化, 需要在支付成功事件后取消短信服务, 只需要让该服务(短信服务)取消订阅相应的事件即可

优势二 : 性能提升, 吞吐量提高

image-20240302145009790

  • 采用 同步调用方案 最后耗时将会是 所有服务耗时之和 即 50 + 10 + 150 + 150 + 150 = 510 ms

  • 采用 异步调用方案 最后耗时则只是 支付服务和发布支付时间(不需要阻塞)之和 即 50 + 10 = 60 ms

​ 同时调用方不需要阻塞等待也避免的了资源浪费问题

优势三 无级联失败风险

image-20240302145955368

 即使仓储服务挂了, 也并不影响其他服务的正常调用, 只需让仓储服务重启重新读取消息即可,

不会导致级联失败

优势四 流量消峰

image-20240302150621712

image-20240302150718238

​ 就像洪水爆发时, 大坝蓄洪一样, 对于激增请求量, 使用队列存储起来, 让服务提供方按照正常的速度消费存储下的消息, 避免因请求激增导致服务压力过载崩掉

**总结: **

异步通信的优点:

  • 耦合度低
  • 吞吐量高
  • 故障隔离
  • 流量削峰

**异步通信的缺点: **

  • 依赖于Broker的可靠性, 安全性, 吞吐能力
  • 架构复杂, 业务没有明显的流程线条, 不好追踪管理

消息队列

MQ ( MessageQueue ), 中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker

RabbitMQ ActiveMQ RocketMQ Kafka
公司社区 Rabbit Apache 阿里 Apache
开发语言 Erlang Java Java Scala & Java
协议支持 AMQP, XMPP, SMTP, STOMP OpenWire, STOMP, REST, XMPP, AMQP 自定义协议 自定义协议
可用性 一般
单机吞吐量 一般 非常高
消息延迟 微秒级 毫秒级 毫秒级 毫秒以内
消息可靠性 一般 一般

RabbitMQ快速入门

RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:https://www.rabbitmq.com

常见消息模型

RabbitMQ 官方文档中提供了 5个Demo, 对应了几种不同的用法:

image-20240302154140024

BasicQueue

image-20240302154219350

总结

基本消息队列的消息发送流程

  • 创建并配置ConnectionFactory

  • ConnectionFactory获取Connection

  • 利用Connection创建channel

  • 利用channel声明队列

  • 利用channel.basicPublish()向队列中发送消息

基本消息队列的消息接受流程

  • 创建并配置ConnectionFactory

  • ConnectionFactory获取Connection

  • 利用Connection创建channel

  • 利用channel声明队列

  • 定义consumer.basicConsume()的消费行为handleDelivery()

  • 利用channel将消费者与队列绑定

SpringAMQP

什么是SpringAMQP

Spring AMQP官网介绍

image-20240302160045581

Work Queue

image-20240302171519113

消息预取机制(preFetch)

Work模型的使用总结

  • 多个消费者绑定到一个队列同一条消息只会被一个消费者处理
  • 通过设置prefetch来控制消费者预取的消息数量

发布订阅模式

发布(Publish), 订阅(Subscribe)

发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机)。

常见的exchange包括

  • Fanout: 广播
  • Direct: 路由
  • Topic: 话题

image-20240302175831057

发布订阅- Fanout Exchange

FanoutExchange会将接收到的消息路由到每一个跟其绑定的queue

image-20240302180259804

image-20240302180426865

总结

交换机的作用是什么?

  • 接收publisher发送的消息
  • 将消息按照规则路由到与之绑定的队列
  • 不能缓存消息路由失败,消息丢失
  • FanoutExchange的会将消息路由到每个绑定的队列

声明队列, 交换机, 绑定关系的Bean是什么?

  • Queue
  • FanoutExchange
  • Binding

发布订阅- Direct Exchange

Direct Exchange会将接收到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)。

  • 每一个Queue都与Exchange设置一个BindingKey
  • 发布者发送消息时,指定消息的RoutingKey
  • Exchange将消息路由到BindingKey与消息RoutingKey一致的队列

image-20240302181910393

还可以绑定多个key, 多个Queue绑定同一个key, 就实现了Fanout Exchange的效果, 所以说Direct Exchange更灵活一些

image-20240302182035976

描述下Direct交换机与Fanout交换机的差异?

  • Fanout 交换机将消息路由给每一个与之绑定的队列
  • Direct交换机根据RoutingKey判断路由给哪个队列
  • 如果多个队列具有相同的Routing Key,则与Fanout功能类似

基于RabbitListener注解的声明队列与交换机有哪些常见的注解?

  • @QueueBanding

  • @Queue

  • @Exchange

发布订阅- Topic Exchange

Topic ExchangeDirect Exchange类似,区别在于routing Key必须是多个单词的列表,并且以**.**分割

QueueExchange指定的BindgingKey时可以使用通配符:

  • # 代表0个或多个单词
  • * 代表一个单词

image-20240302184016983

消息转化器

Spring的对消息对象的处理是由org.springframework.amqp.support..converter.MessageConverter来处理的。而
默认实现是SimpleMessageConverter,基于JDK的ObjectOutputStream完成序列化

SpringAMQP中消息的序列化和反序列化是怎么实现的?J

  • 利用MessageConverter实现的,默认是JDK的序列化
  • 注意发送方与接收方必须使用相同的MessageConverter