MQ消息队列

什么是消息队列

我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。
消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能削峰降低系统耦合性

通过异步处理提高系统性能(减少响应所需时间)

在这里插入图片描述
因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此使用消息队列进行异步处理之后,需要适当修改业务流程进行配合,比如用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷。这就类似我们平时手机订火车票和电影票。

削峰/限流

先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉。

降低系统耦合性

生产者(客户端)发送消息到消息队列中去,接受者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合, 这显然也提高了系统的扩展性。

消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计

另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。

使用消息队列带来的一些问题

  • 系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了!
  • 系统复杂性提高: 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!
  • 一致性问题: 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了!

MQ 的常见问题有:

消息的顺序问题
消息的重复问题

消息的顺序问题

消息有序指的是可以按照消息的发送顺序来消费。

解决:
(1)保证生产者 - MQServer - 消费者是一对一对一的关系
缺陷:

  • 并行度就会成为消息系统的瓶颈(吞吐量不够)
  • 不关注乱序的应用实际大量存在
  • 队列无序并不意味着消息无序 所以从业务层面来保证消息的顺序而不仅仅是依赖于消息系统,是一种更合理的方式。

消息的重复问题

造成消息重复的根本原因是:网络不可达

消费端处理消息的业务逻辑保持幂等性只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样。保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现。利用一张日志表来记录已经处理成功的消息的 ID,如果新到的消息 ID 已经在日志表中,那么就不再处理这条消息。

JMS vs AMQP

在这里插入图片描述

常见的消息队列对比

在这里插入图片描述
总结:

  • ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。
  • RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做erlang源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
  • RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用RocketMQ 挺好的
  • Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。
### MQ 消息队列的使用教程与解决方案 #### 一、常见 MQ 消息队列产品的选择 在现代分布式系统中,消息队列(Message Queue, MQ)是一个重要的组件。常见的 MQ 消息队列产品包括 RabbitMQ、Kafka、ZeroMQ 和 ActiveMQ 等[^1]。每种产品都有其特定的优势和适用场景: - **RabbitMQ**: 基于 AMQP 协议实现的消息中间件,适合用于复杂的路由规则和高可靠性需求的应用场景。 - **Kafka**: 高吞吐量的日志收集和流数据处理平台,适用于大数据分析和实时数据管道构建。 - **ZeroMQ**: 提供轻量级的消息传递库,支持多种模式下的高性能通信。 - **ActiveMQ**: 功能全面的企业级消息中间件,兼容 JMS 标准。 #### 二、MQ 的基础功能及其优势 MQ 的核心功能在于提供可靠的消息通信机制。具体来说,它可以完成以下几个方面的工作[^2]: - **消息通信**: 客户端可以通过生产者将消息发送至 MQ 并由消费者获取这些消息。 - **异步处理**: 生产者无需等待消费者的响应即可继续执行其他操作,从而提升系统的整体性能。 - **应用解耦**: 不同模块之间通过消息队列进行交互,减少了直接依赖关系。 - **削峰填谷**: 当流量激增时,利用消息队列缓冲请求,避免下游服务因瞬时压力过大而导致崩溃。 #### 三、典型应用场景解析 以下是几种典型的 MQ 使用场景以及对应的解决思路[^3][^4]: ##### 场景 1: 秒杀活动中的订单处理 对于电商网站上的秒杀活动而言,短时间内可能会涌入大量用户提交订单请求。如果直接让数据库承受如此高的访问频率,则极有可能造成系统瘫痪。此时可采用如下策略: 1. 将用户的下单请求先存入消息队列; 2. 如果队列长度超出预设阈值,则拒绝新增加的请求或者引导客户查看错误提示页; 3. 后台工作线程按固定速率依次取出待处理的任务并进一步验证库存状态等逻辑后再决定是否真正创建该笔交易记录。 ```python import pika def send_order_to_queue(order_id): connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() queue_name = 'seckill_orders' max_length = 1000 arguments={ 'x-max-length':max_length, 'x-overflow':'reject-publish', } channel.queue_declare(queue=queue_name,durable=True,arguments=arguments) message=str(order_id) channel.basic_publish(exchange='',routing_key=queue_name,body=message) print(f"[x] Sent {message}") connection.close() send_order_to_queue(1234567890) ``` ##### 场景 2: 日志采集与监控 企业内部往往存在多个独立运行的服务实例,它们各自产生的日志文件难以统一管理。借助 Kafka 可以搭建一套集中式的日志管理系统: 1. 所有的微服务都将自身的运行状况信息推送到指定主题上; 2. 数据分析师可以从订阅渠道读取原始资料进而开展探索性研究项目比如异常检测预警等等。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值