消息中间件学习总结(20)——主流MQ比较及MQ常见使用场景总结

本文总结了消息中间件的主要角色,包括ZeroMQ、RabbitMQ、ActiveMQ、Redis和Kafka的特点,并探讨了何时需要引入消息队列,如解耦、最终一致性、广播和错峰流控等场景。此外,分析了MQ的优缺点,强调了在分布式系统中,MQ作为解耦工具和流量控制的重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据机构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

解耦:一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。异步:主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。

削峰:高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。

MQ同时也有其缺点:1、系统可用性降低。依赖服务也多,服务越容易挂掉。需要考虑MQ瘫痪的情况;2、系统复杂性提高。需要考虑消息丢失、消息重复消费、消息传递的顺序性;3、业务一致性。主业务和从属业务一致性的处理。

一、主流MQ

1、ZeroMQ

号称最快的消息队列系统,尤其针对大吞吐量的需求场景。扩展性好,开发比较灵活,采用C语言实现,实际上只是一个socket库的重新封装,如果做为消息队列使用,需要开发大量的代码。ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。其中,Twitter的Storm中使用ZeroMQ作为数据流的传输。

2、RabbitMQ

### 关于消息队列 MQ常见面试题及其解答 #### 1. 生产者丢失消息的原因及解决方案 生产者可能会因为网络传输中的丢包或者消息队列服务端发生异常未能成功接收消息而导致消息丢失。为了防止这种情况的发生,主流的消息队列产品通常提供了确认机制或事务支持功能来保障消息能够被可靠地传递至消息队列服务器。例如,在 RabbitMQ 中存在两种主要方式用于确保消息不会丢失——事务模式和 Confirm 模式[^1]。 #### 2. 如何保证消息的顺序性? 对于某些业务场景而言,保持消息按特定次序处理是非常重要的需求之一。RabbitMQ 可通过配置单线程消费者以及设置 `prefetch_count=1` 来实现这一目标。这意味着每次只允许一个未完成的任务分配给某个具体的消费者实例直到前一任务结束为止从而维持全局有序性[^3]。 #### 3. 部署复杂度与运维挑战 随着企业规模扩大和技术架构日益复杂化, 对应地也提高了对开发人员特别是 DevOps 工程师们的技术水平要求。他们不仅需要熟悉各种开源工具链如 Docker/Kubernetes 等容器编排平台的知识点外还需掌握诸如 Kafka/Zookeeper 或 Pulsar/BookKeeper 类型分布式流计算框架的工作原理以便更好地管理和维护整个系统生命周期内的稳定性表现良好性能指标达成预期效果满足实际应用场景下的多样化需求特点[^2]. #### 4. 数据库写入与缓存更新的一致性问题 当应用程序既涉及到了数据库记录修改又包含了关联对象存储(比如Redis)状态刷新时,则很容易遇到因时间差造成两者间短暂不同步的现象。一种可行的办法就是在执行SQL语句之前先把对应变动通知推送到中间件上等待后续由专门负责监听该主题订阅者的回调函数再去主动触发相应的动作以此达到最终一致性的目的尽管在此过程中可能存在短暂时延使得部分查询请求返回陈旧版本的信息内容但是总体来说这种方法兼顾了吞吐量提升的同时又能较好控制风险范围不至于影响整体服务质量水准下降太多程度范围内可接受的程度之内[^4]。 ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() def update_cache(message): # Simulate cache updating logic here. pass def on_message(ch, method, properties, body): message = json.loads(body.decode()) try: with database_transaction(): process_database_update(message) ch.basic_ack(delivery_tag=method.delivery_tag) update_cache(message) except Exception as e: logging.error(f"Failed to handle message {message}: {e}") ch.basic_nack(delivery_tag=method.delivery_tag) channel.basic_consume(queue='task_queue', on_message_callback=on_message) channel.start_consuming() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯甜酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值