MQ
初识MQ
同步调用存在的问题
1.耦合度高
每次加入新的需求,都要修改原来的代码。
2.性能下降
调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和。
3.资源浪费
调用链中的每个服务在等待响应的过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源。
4.级联失败
如果服务者出现问题,所有调用方都会跟着出现问题。
同步调用的优点
时效性较强,可以立即得到结果。
异步调用
异步调用常见的实现就是事件驱动模式。
事件驱动优势
优势一:服务解耦
优势二:性能提升,吞吐量提高
优势三:服务没有强依赖,不用担心级联失败问题。
优势四:流量削峰。
异步通信的优点:
耦合度低
吞吐量提升
故障隔离
流量削峰
异步通信的缺点:
依赖于Broker的可靠性,安全性,吞吐能力。
架构复杂了,业务没有明显的流程线,不好追踪管理。
什么是MQ
MQ,中文是消息队列,字面来看就是存放消息的队列。也就是时间驱动架构中的Broker
GRZ60N7(6.png)
RabbitMQ快速入门
RabbitMQ是指基于Erlang语言开发的开源消息通信中间件。
RabbitMQ中的几个概念
channel:操作MQ的工具
exchange:路由消息到队列中
queue:缓存消息
virtual host:虚拟主机,是对queue,exchange等资源的逻辑分组
常见消息模型
基本消息队列(BasicQueue)
工作消息队列(WorkQueue)
发布订阅(Publish,Subscribe),又根据交换机类型的不同分为三种:
Fanout Exchange:广播
Direce Exchange:路由
Topic Exchange:主题
基本消息队列的消息发送流程
1.建立connection
2.创建channel
3.利用channel声明队列
4.利用channel向消息队列发送消息
基本消息队列的消息接收流程
1.建立connection
2.创建channel
3.利用channel声明队列
4.定义consumer的消费行为handleDelivery()
5.利用channel将消费者与队列绑定
SpringAMQP
什么是SpringAMQP?
AMQP是用于在应用程序或之间传递业务消息的开放标准。该协议与语言平台无关,更符合微服务中独立性的要求。
SpringAMQP是基于AMQP协议定义的一套API规范,提供了模版来发送和接受消息。包括两部分,其中Spring-amqp是基础抽象,spring-rabbit是底层的默认实现。
SpringAMQP如何发送消息?
引入amqp的stater依赖
配置RabbitMQ地址
利用RabbitTemplate的convertSend方法
SpringAMQP如何接受消息?
引入amqp的stater依赖
配置RabbitMQ地址
定义类,添加@Component
类中声明方法,添加@RabbitListener,方法参数就是消息
Work模型的使用
多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
通过设置prefetch来控制消费者预取的消息数量
发布(Publish)订阅(Subscribe)
发布订阅模式允许将同一消息发送给多个消费者。实现方式就是加入了exchange(交换机)
发布订阅-Fanout Exchange
Fanout Exchange会将接收到的消息路由带每一个跟其绑定的queue
交换机的作用是什么?
接受publisher发送的消息
将消息按照规则路由到与之前绑定的队列
不能缓存消息,路由失败,消息丢失
FanoutExchange的会将消息路由到每个绑定的队列
声明队列、交换机,绑定关系的Bean是什么?
Queue
FanoutExchange
Binding
发布订阅-DirectExchange
DirectExchange会将接受到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)
每一个Queue都与Exchange设置一个Bindingkey
发布者发送消息是,指定消息的RoutingKey
Exchange将消息路由到BindingKey与消息RoutingKey一致的队列
描述下Direct交换机与Fanout交换机的差异?
Fanout交换机将消息路由给每一个与之绑定的队列
Direct交换机根据RoutingKey判断路由给那个队列
如果多个队列具有相同的RoutingKey,则与Fanout功能类似
基于@RabbitListener注解声明队列和交换机有哪些常见注解?
@Queue
@Exchange
发布订阅-TopicExchange
TopicExchange与DirectExchange类似,区别在于routingKey可以是多个单词的列表,并且以.分隔
消息转换器
SpringAMQP中消息的序列化和反序列化是怎么实现的?
利用MessageConverter实现的,默认是JDK的序列化
注意发送方与接收方必须使用相同的MessageConverter