初识消息队列
一.同步调用和异步调用的差别和优势
1.同步调用:
缺点:
①拓展性差:代码冗余在了一起,所以拓展性差。
②性能下降:调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和。
③级联失败:由于我们是基于OpenFeign调用交易服务、通知服务。当交易服务、通知服务出现故障时,整个事务都会回滚,交易失败。
这其实就是同步调用的级联失败问题。优点:
①时效性强,等待到结果后才返回。
2.异步调用
优点:
①耦合度更低
②性能更好
③业务拓展性强
④故障隔离,避免级联失败缺点:
①完全依赖于Broker的可靠性、安全性和性能
②架构复杂,后期维护和调试麻烦③不确定下游业务执行是否成功
3.使用
我们要在合适的场景使用合适的调用技术
二.消息队列的一些概念
1.mq整体交互的流程图:
2.Producer和Consumer
Producer: ⽣产者, 是RabbitMQ Server的客⼾端, 向RabbitMQ发送消息
Consumer: 消费者, 也是RabbitMQ Server的客⼾端, 从RabbitMQ接收消息
Broker:其实就是RabbitMQ Server, 主要是接收和收发消息
• ⽣产者(Producer)创建消息, 然后发布到RabbitMQ中. 在实际应⽤中, 消息通常是⼀个带有⼀定业务逻辑结构的数据, ⽐如JSON字符串. 消息可以带有⼀定的标签, RabbitMQ的exchange会根据标签进⾏路由, 把消息发送给感兴趣的消费者(Consumer).• 消费者连接到RabbitMQ服务器, 就可以消费消息了, 消费的过程中, 标签会被丢掉. 消费者只会收到消息, 并不知道消息的⽣产者是谁, 当然消费者也不需要知道.
• 对于RabbitMQ来说,⼀个RabbitMQ Broker可以简单地看作⼀个RabbitMQ服务节点, 或者RabbitMQ服务实例. ⼤多数情况下也可以将⼀个RabbitMQ Broker看作⼀台RabbitMQ服务器
3.Connection和Channel
Connection: 连接. 是客⼾端和RabbitMQ服务器之间的⼀个TCP连接. 这个连接是建⽴消息传递的基础, 它负责传输客⼾端和服务器之间的所有数据和控制信息.
Channel: 通道, 信道. Channel是在Connection之上的⼀个抽象层. 在 RabbitMQ 中, ⼀个TCP连接可以有多个Channel, 每个Channel 都是独⽴的虚拟连接. 消息的发送和接收都是基于 Channel的.
通道的主要作⽤是将消息的读写操作复⽤到同⼀个TCP连接上,这样可以减少建⽴和关闭连接的开销, 提⾼性能.
4.Virtual host
Virtual host: 虚拟主机. 这是⼀个虚拟概念. 它为消息队列提供了⼀种逻辑上的隔离机制. 对于RabbitMQ⽽⾔, ⼀个 BrokerServer 上可以存在多个 Virtual Host. 当多个不同的⽤⼾使⽤同⼀个RabbitMQ Server 提供的服务时,可以虚拟划分出多个 vhost,每个⽤⼾在⾃⼰的 vhost 创建 exchange/queue 等
5.Queue
Queue: 队列, 是RabbitMQ的内部对象, ⽤于存储消息.
6.Exchange
Exchange: 交换机. message 到达 broker 的第⼀站, 它负责接收⽣产者发送的消息, 并根据特定的规则把这些消息路由到⼀个或多个Queue列中.
Exchange起到了消息路由的作⽤,它根据类型和规则来确定如何转发接收到的消息.
注意:只负责转发消息,不具备存储消息的能力
三.AMQP
AMQP(Advanced Message Queuing Protocol)是⼀种⾼级消息队列协议, AMQP定义了⼀套确定的消息交换功能, 包括交换器(Exchange), 队列(Queue) 等. 这些组件共同⼯作, 使得⽣产者能够将消息发送到交换器. 然后由队列接收并等待消费者接收. AMQP还定义了⼀个⽹络协议, 允许客⼾端应⽤通过该协议与消息代理和AMQP模型进⾏交互通信
RabbitMQ是遵从AMQP协议的,换句话说,RabbitMQ就是AMQP协议的Erlang的实现(当然RabbitMQ还⽀持STOMP2, MQTT2等协议). AMQP的模型结构和RabbitMQ的模型结构是⼀样的.
四.简单的使用rabbitmq的步骤
1.引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置yml文件
spring:rabbitmq:host: 192.168.150.101 # 你的虚拟机IPport: 5672 # 端口virtual-host: /hmall # 虚拟主机username: hmall # 用户名password: 123 # 密码
3.发送消息
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSimpleQueue() {// 队列名称String queueName = "simple.queue";// 消息String message = "hello, spring amqp!";// 发送消息rabbitTemplate.convertAndSend(queueName, message);}
}
4.接受消息
@Component
public class SpringRabbitListener {// 利用RabbitListener来声明要监听的队列信息// 将来一旦监听的队列中有了消息,就会推送给当前服务,调用当前方法,处理消息。// 可以看到方法体中接收的就是消息体的内容@RabbitListener(queues = "simple.queue")public void listenSimpleQueueMessage(String msg) throws InterruptedException {System.out.println("spring 消费者接收到消息:【" + msg + "】");}
}