MQ(MessageQueue)的学习使用

一、MQ

1、消息的通讯机制同步异步的定义:
(1)所谓同步,就是发起调用后,被调用者处理消息,必须等处理完才直接返回结果,没处理完之前是不返回的,调用者主动等待结果;
(2)所谓异步,就是发起调用后,被调用者直接返回,但是并没有返回结果,等处理完消息后,通过状态、通知或者回调函数来通知调用者,调用者被动接收结果。

2、同步通讯
(1)优点:
时效性较强,可以立即得到结果。

(2)缺点:
微服务间基于Feign的调用就属于同步方式,存在一些问题。
1)耦合问题
  业务增加导致代码迭代开发,复杂度增加,耦合度增加,维护难度加大
2)性能问题
  业务复杂情况下,服务间的调用关系复杂,同步调用决定着调用时间会剧增,性能下降,吞吐量下降
3)资源浪费问题
  调用者必须等待提供者响应才能接着往下调用,这样就形成长期占用CPU以及内存的局面,造成资源利用不够充分,大量资源的浪费。
4)级联失败问题
  调用链中某个服务提供者挂了,调用者就会一直等着,当请求越来越多就都会阻塞,调用者服务资源被耗尽,请求都会进不来,直接“炸”了。
  
如下图所示:
在这里插入图片描述
3、异步通讯
异步调用常见实现就是事件驱动模式
在这里插入图片描述
(1)优点:
1)服务解耦
  不再通过服务调用者来直接调用服务提供者,增改业务也不会再需要直接改动服务调用者的代码,而是用过Broker进行事件驱动。
2)性能提升,吞吐量提高
  总体业务耗时从服务调用者到每个服务提供者相加的结果变为服务调用者耗时加上通知Broker的耗时,大大缩短耗时。
3)服务没有强依赖,不担心级联失败问题
  不再会因为一个服务提供者挂掉而影响到服务调用者。
4)流量削锋
  Broker起到抗压和保护的作用,实现流量削峰。
  
(2)缺点
1)依赖于Broker的可靠性、安全性、吞吐能力;
2)架构复杂了,业务没有明显的流程线,不好追踪管理。

4、MQ常见框架
在这里插入图片描述

二、RabbitMQ

1、RabbitMQ概述和安装
(1)概述
RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:https://www.rabbitmq.com/
在这里插入图片描述
1)channel:操作MQ的工具
2)exchange:路由消息到队列中
3)queue:缓存消息
4)virtual host:虚拟主机,是对queue、exchange等资源的逻辑分组

2、常见消息模型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为什么发送和接受消息都要声明队列?
  避免队列不存在,保险行为。

三、SpringAMQP

AMQP(Advanced Messaged Queuing Protocol,高级消息队列协议)
  消息队列的规范,与任何语言和平台无关,符合微服务的技术独立性需求。
SpringAMQP
  基于AMQP协议定义的一套API规范,提供了模板来发送和接受消息。官网地址:https://spring.io/projects/spring-amqp
SpringAMQP的特性:
(1)用于异步处理入站消息的侦听器容器
(2)用于发送和接收消息的RabbitTemplate
(3)RabbitAdmin用于自动声明队列、交换和绑定
在这里插入图片描述

1、Basic Queue 简单队列模型
在这里插入图片描述
消息发送:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
消息接收:
在这里插入图片描述
在这里插入图片描述
2、Work Queue 工作队列模型
Work Queue,工作队列,可以提高消息处理速度,避免队列消息堆积
在这里插入图片描述
注意:
  简单队列模型只有一个消费者,效率偏低,当队列中消息堆积到饱和点,新来的消息会被删除,这样就会有问题(消息丢失),工作队列采用两个消费者则是效率上相较于简单队列会有提升,一个消息被消费队列中就会删除该消息,这样就能一定程度上避免消息堆积而导致的消息丢失。
在这里插入图片描述
消息预取机制:
体现“能者多劳”,充分利用服务性能,防止了一部分的资源浪费。
在这里插入图片描述
在这里插入图片描述
发布订阅模式:
在这里插入图片描述
3、发布、订阅模型-Fanout
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述

4、发布、订阅模型-Direct
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5、发布、订阅模型-Topic
在这里插入图片描述
案例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、消息转换器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、基于MQ的异步通知,在哪些业务场景中可以用到?

为了更加直观的展现MQ的应用场景,这里咱们就用一个常见的电商系统中的几个业务,来具体说明下MQ在实际开发中应用场景。
  咱们的实际场景大概是一个基于微服务架构的电商系统,分为用户微服务、商品微服务、订单微服务、促销微服务等。基于微服务模式开发的系统,MQ的使用场景更多,下面咱们逐一说明:
  1、注册后咱们可能须要作不少初始化的操做,如:调用邮件服务器发送邮件、调用促销服务赠送优惠劵、下发用户数据到客户关系系统等。那么这时候咱们将这些操做去监听MQ,当用户注册成功事后,经过MQ通知其余业务进行操做。确保注册用户的性能。
  2、后台发布商品的时候,商品数据须要从数据库中转换成搜索引擎数据(基于elasticsearch),那么咱们应该将商品写入数据库后,再写入到MQ,而后经过监听MQ来生成elasticsearch对应的数据。
  3、用户下单后,24小时未支付,须要取消订单。之前咱们多是定时任务循环查询,而后取消订单。实际上,我更推荐相似延迟MQ的方式,避免了不少无效的数据库查询,将一个MQ设置为24小时后才让消费者消费掉,这样很大程度上能减轻服务器压力。
  4、支付完成后,须要及时的通知子系统(进销存系统发货,用户服务积分,发送短信)进行下一步操做,可是,支付回调咱们都是须要保证高性能的,因此,我应该直接修改数据库状态,存入MQ,让MQ通知子系统作其余非实时的业务操做。这样能保证核心业务的高效及时。
注意事项:
  其实,还有很是多的业务场景,是能够考虑用MQ方式的,可是不少时候,也会存在滥用的状况,咱们须要清楚认识咱们的业务场景:
  发验证码短信、邮件,这种过度依赖外部,并且时效性能够接收几十秒延迟的,其实更好的方式是多线程异步处理,而不是过多依赖MQ。
  秒杀抢购确保库存不为负数,更多的依赖高性能缓存(如redis),以及强制加锁,千万不要依赖消费者最终的返回结果。(实际工做中已经看到好几个这样的案例了)上游-下游 这种直接的处理方式效率确定是比 上游-MQ-下游 方式要高,MQ效率高,是由于,我只是上游-MQ 这个阶段就当作已经成功了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python FastAPI 是一个快速(高性能)且易于学习的 Web 框架,它可以与多种消息队列(MQ)进行集成,其中包括 RabbitMQ。 在使用 FastAPI 和 RabbitMQ 进行集成时,你可以使用 Pika 库来连接 RabbitMQ,然后在 FastAPI 中使用 FastAPI-BackgroundTasks 库来异步处理消息队列中的消息。以下是一个简单的示例: 1. 安装 FastAPI 和 Pika 库: ```python pip install fastapi pip install pika pip install fastapi-background-tasks ``` 2. 在 FastAPI 应用程序中导入相关库: ```python from fastapi import FastAPI, BackgroundTasks import pika ``` 3. 连接 RabbitMQ: ```python connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue='my_queue') ``` 4. 编写处理函数,并在函数中使用 `channel.basic_publish()` 方法将消息发布到消息队列中: ```python def process_message(message): # 处理消息的代码 print("Received message:", message) def send_message_to_queue(message): channel.basic_publish(exchange='', routing_key='my_queue', body=message) ``` 5. 在 FastAPI 中定义异步任务: ```python app = FastAPI() @app.post("/send_message") async def send_message(message: str, background_tasks: BackgroundTasks): background_tasks.add_task(send_message_to_queue, message) return {"message": "Message sent successfully!"} @app.on_event("startup") async def startup_event(): connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue='my_queue') channel.basic_consume(queue='my_queue', on_message_callback=process_message, auto_ack=True) channel.start_consuming() ``` 6. 启动应用程序: ```python uvicorn main:app --reload ``` 这是一个简单的示例,你可以根据你的需求进行调整和扩展。下面是一些相关问题:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值