
前言首先我提一点我自己的学习心得我通过最近学习项目我觉得我们在学习新技术的时候要始终记得有一个前提技术的诞生是为了解决问题。我们不要为了学而去学这样其实没自己思考学的和理解的也比较慢我在以前学习的时候就是因为别人项目用了所以我去学这是不对的我们应该带着问题去学比如我之前学过rabbitmq那我现在为什么会去学kafka和rocketmq不是简单的因为大家都用我去学而是如果未来遇到了大量数据日志处理这种需要巨大的吞吐量那rabbitmq就不行了在比如我业务需要高可靠性比如涉及到钱那rocketmq的事务消息就可以排上用场了。这是我在学习过程中叫ai写的一个静态网页。本文将基于这个网页的核心内容带你从不同视角拆解三大 MQ网站地址mqlearn诞生背景理解一款中间件首先要回到它诞生的场景。三款 MQ 的起点完全不同这直接决定了它们的设计哲学。1. RabbitMQ —— 金融基因追求可靠与灵活路由2007 年诞生源自金融领域的需求银行、证券交易所。率先实现 AMQP 0-9-1 协议核心理念是“让中间件负责消息路由”。天然追求极高的可靠性和灵活的消息分发比如支持 direct、topic、fanout、headers 四种交换机路由能力在三者中最强。2. RocketMQ —— 电商基因追求高并发下的强一致与事务阿里巴巴自研起源于双十一的超高并发交易场景。设计目标非常明确在十万级 QPS 下保证消息不丢、顺序不乱、事务一致。自带事务消息分布式事务终极方案之一、同步刷盘、同步复制是金融级可靠性的代名词。3. Kafka —— 大数据基因追求极致吞吐与数据回溯2011 年 LinkedIn 开发用于实时处理海量用户行为日志。设计哲学是把消息看作一条无界的“流”追求单机百万级吞吐、消息持久化和可任意回放。顺序写盘 零拷贝sendfile技术使其成为大数据生态的事实标准。核心特点差异特点RabbitMQ (仲裁队列)RocketMQKafka持久化消息声明 persistent依赖 OS 刷盘同步刷盘立即写磁盘依赖 Page Cache 异步刷盘靠副本保证可靠吞吐量万级 QPS十万级 QPS百万级 QPS路由灵活度四种交换机极其灵活通过 Topic Tag 区分主要通过 Topic 和 Key 哈希消息顺序单 Queue 内严格有序单 MessageQueue 有序单 Partition 有序消息回溯不支持支持但不如 Kafka 灵活支持任意 offset 重置天然可回放高可用仲裁队列 (Raft)Dledger (Raft)ISR Leader 选举事务消息不支持原生支持两阶段不支持可以看到RocketMQ 和 RabbitMQ 更注重单条消息的可靠性和路由精细度而 Kafka 则把“快”和“数据流”发挥到了极致。架构设计RabbitMQ 的架构单节点Producer → Exchange → Queue通过 Binding Key 绑定→ Consumer集群镜像队列已逐步废弃或仲裁队列。仲裁队列基于 Raft 协议写入需过半节点确认自动选主解决脑裂问题。2. RocketMQ 的架构单节点Producer → BrokerCommitLog 顺序写盘→ MessageQueue → Consumer集群Master-Slave 同步复制 DledgerRaft 实现自动选主。NameServer 作为去中心化路由中心极轻量。3. Kafka 的架构单节点Producer → BrokerPartition 日志文件→ Consumer集群每个 Partition 一主多从通过ISRIn-Sync Replicas动态管理同步副本只从 ISR 中选新 Leader。元数据管理从 ZooKeeper 进化为KRaftKafka 自己的 Raft 实现。常见消息队列问题消息丢失丢失消息我们要知道为什么丢从哪儿丢其实无非就是生产者 ——》mq—— 》 消费者。无非就这条路上所以三种mq的解决思路其实也都是在这条路上。通用思路生产端发送确认 失败重试存储端多副本持久化 同步复制/多数派写入消费端先处理业务后提交/确认MQ独有机制RabbitMQ仲裁队列• 基于 Raft 多数派写入写入过半数节点才返回成功• Publisher Confirm发送方确认• 消息和队列强制持久化RocketMQ• 同步刷盘 同步复制DLedger 模式• DLedger 基于 Raft 自动故障转移确保多数副本落盘• 事务消息保证本地事务与发消息原子性Kafka•acksallmin.insync.replicas ≥ 2• 只从 ISR 中选举新 Leader落后副本不能当选• 可开启幂等生产者避免网络重试导致重复但主要防重复重复消费其实这个也就是幂等性问题在业务中我所知道的就一下几种。1.通过redistoken简单来说就是用户进入页面前端发请求然后后端给token并存redis用户真正点击提交前端携带数据和token后端直接删除token如果成功说明没有如果失败说明有。2.数据库唯一索引这种方式我们一般来说都是作为兜底比如优惠券业务数据库对优惠券id和用户id建立唯一索引那么同一用户购买两张一样的就会失败数据库只会插入一条数据。3.还可以用redis的setnx命令通过set key value nx ex ms 像这个key的话可以用uuid如果设置成功那就可以设置失败那就不行过期时间的话1小时或者更久或者几分钟。这里有一个极端问题万一key一样咋办我通过ai了解到可以用hashkey这样redis的value就是hashkey,不再是只要key设置失败就行而是value也一样才行。消息堆积通用思路增加消费者实例水平扩展消费端限流控制拉取频率/prefetch设置消息保留时间过期自动清理或转移死信队列各 MQ 独特方案MQ独有实现RabbitMQ•惰性队列Lazy Queue消息直接存磁盘堆积亿级不占内存• 仲裁队列本身数据在磁盘天然抗堆积•basic.qos控制 prefetch精细限制消费者处理速率RocketMQ• CommitLog 顺序写堆积不影响性能• 消费进度管理消息可回溯• 队列数决定并行度需提前规划扩容不易Kafka• 分区数限制最大并行度堆积时需增加分区影响顺序• 日志保留策略按时间/大小自动清理• 新版本分级存储Tiered Storage冷数据入廉价对象存储避免磁盘爆满总结更详细的内容可以在静态网页里面看不要去背去理解然后时不时打开这篇文章看看或者打开网页看看。网站地址mqlearn唉在这个所有人卷到飞起世界我甚至不知道这条路到底对不对不过我有一个想法就是反正人吧就这么活一次而已我总得有一个我自己擅长的领域吧就当爱好了哪怕以后吃不上这碗饭也无妨了我还是会持续开发和我的codex创造出一个伟大的让后续的计算机学生一看见就直呼卧槽的项目和设计。就当意淫了。