MQ
一、同步调用和异步调用
1. 同步调用
微服务一旦拆分,必然涉及到服务之间的相互调用,目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才能继续执行后面的业务。也就是说调用者在调用过程中处于阻塞状态,因此我们称这种调用方式为同步调用,也可以叫同步通讯。但在很多场景下,我们可能需要采用异步通讯的方式。
以下方式不一定都必须使用同步调用。
同步调用缺点:
- 拓展性差:每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动,不符合开闭原则,拓展性不好。
- 性能下降:由于我们采用了同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和。
- 级联失败:一个服务失败会导致后面的都没办法正常执行
2. 异步调用
异步调用方式其实就是基于消息通知的方式,一般包含三个角色:
- 消息发送者:投递消息的人,就是原来的调用方
- 消息Broker:管理、暂存、转发消息,你可以把它理解成微信服务器
- 消息接收者:接收和处理消息的人,就是原来的服务提供方
二、RabbitMQ
1. 基础使用
- 我们同样基于Docker来安装RabbitMQ。
- 安装完成后,我们访问 http://192.168.150.101:15672即可看到管理控制台。首次访问需要登录,默认的用户名和密码在配置文件中已经指定了。
- publisher:生产者,也就是发送消息的一方
- consumer:消费者,也就是消费消息的一方
- queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
- exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
- virtual host:虚拟主机,起到数据隔离的作用。每个虚拟主机相互独立,有各自的exchange、queue
个人理解:
用这个图举例子,已知2已经修改完支付状态
生产者发送给交换机:支付服务把支付成功消息发送给消息代理
交换机通过路由策略把消息发送给特定队列
交易服务、通知服务,这些服务代表消费者,都在监听和他们绑定的队列,一旦队列中有消息就读取,执行对应操作。
虚拟主机的意思:一个项目可能对应一个MQ虚拟主机,以后有其他项目再新建一个虚拟主机
2. 实际操作 怎么用?
- 新建交换机
- 新建队列
- 绑定交换机和队列
- 发送消息测试
注意:交换机不能存储消息,只能路由
3. RabbitMQ虚拟主机 数据隔离
首先就要建立用户
- 层次关系:每个用户操作同一个项目都得有自己的虚拟主机,不能操作别人的虚拟主机
4. 在JAVA中实现RabbitMQ
发送者发送消息
消费者接收消息
1. workQueue
如果有两个消费者,因为刚开始消费者处理消息都是轮流处理,但是有的消费者能力强,有的弱,但是仍然是轮流处理,这样会导致效率变慢,因此修改消费者的消费策略。
5. 交换机种类
1. Fanout交换机(广播)
2. Direct交换机(指定部分队列)
3. Topic交换机
不同队列对应不同主题,用bindingkey设置,当消息发送时都会指定一个routingkey,如果这个消息符合某个bindingkey,则发送到指定队列上。
6. 基于代码生成交换机
7.基于注解声明交换机
在消息接收者处使用@RabbitListener注解进行声明交换机和注解
8. 消息转换器
所以使用json序列化代替默认的JDK序列化