-
//发送短信消息 for (int i=0;i<10;i++){ String message = "sms inform to user"+i; channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms", null,message.getBytes()); System.out.println("Send Message is:'" + message + "'"); } //发送短信和邮件消息 for (int i=0;i<10;i++){ String message = "sms and email inform to user"+i; channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms.email", null, message.getBytes()); System.out.println("Send Message is:'" + message + "'"); }"inform.sms.email" 这个路由键(Routing Key)会同时发送给 queue_inform_sms 和 queue_inform_email 两个队列,而不是只发给短信队列。可能是你对绑定键(Binding Key)的匹配规则理解有偏差,具体原因如下:关键原因:绑定键的通配符匹配逻辑在之前的消费者代码中,我们给两个队列设置的绑定键(Binding Key)是:queue_inform_email 绑定了 inform.email.#queue_inform_sms 绑定了 inform.sms.#而 Topic 交换机的通配符 # 表示 “匹配零个或多个单词”(单词以 . 分隔)。当路由键是 inform.sms.email 时:对于 queue_inform_sms 的绑定键 inform.sms.#:路由键 inform.sms.email 可以拆分为 inform、sms、email 三个单词,inform.sms.# 会匹配 “以 inform.sms 开头的任意单词组合”,因此匹配成功,短信队列会收到消息。对于 queue_inform_email 的绑定键 inform.email.#:路由键 inform.sms.email 中包含 inform.email 这个片段(最后两个单词),但绑定键 inform.email.# 要求 “以 inform.email 开头”,而实际路由键是以 inform.sms 开头的,因此匹配失败,邮件队列不会收到消息。举例验证:路由键(Routing Key)邮件队列绑定键 inform.email.#短信队列绑定键 inform.sms.#结果(哪个队列收到消息)inform.email匹配(以 inform.email 开头)不匹配仅邮件队列inform.sms不匹配匹配(以 inform.sms 开头)仅短信队列inform.sms.email不匹配(开头是 inform.sms)匹配(以 inform.sms 开头)仅短信队列inform.email.sms匹配(以 inform.email 开头)不匹配仅邮件队列如何让 inform.sms.email 同时发给两个队列?如果需要 inform.sms.email 同时路由到两个队列,需要调整邮件队列的绑定键,例如:邮件队列绑定 inform.#.email(匹配 “以 inform 开头,中间任意单词,最后是 email” 的路由键)。 此时 inform.sms.email 会同时匹配 inform.sms.#(短信队列)和 inform.#.email(邮件队列),两个队列都会收到消息。总结:inform.sms.email 只发给短信队列,是因为邮件队列的绑定键 inform.email.# 要求路由键必须以 inform.email 开头,而该路由键实际以 inform.sms 开头,不符合邮件队列的匹配规则。这是 Topic 交换机通配符精确匹配的结果。
-
在 RabbitMQ 中,交换机(Exchange)是消息路由的核心组件,负责将生产者发送的消息路由到对应的队列。不同类型的交换机通过不同的路由规则工作,fanout、topic、direct、headers 是四种常见类型,核心区别在于路由键(Routing Key)与绑定键(Binding Key)的匹配规则。1. Direct(直接交换机)路由规则:消息的 Routing Key 必须与队列和交换机绑定的 Binding Key 完全一致(精确匹配)。适用场景:需要精确路由的场景,例如 “错误日志”“订单通知” 等明确分类的消息。示例: 交换机绑定队列 Q1 时指定 Binding Key = "error",则只有 Routing Key = "error" 的消息会被路由到 Q1。2. Fanout(扇出交换机)路由规则:忽略 Routing Key 和 Binding Key,将消息广播到所有与该交换机绑定的队列(只要绑定就会收到消息)。特点:路由速度最快(无需匹配),属于 “群发” 机制。适用场景:需要将消息同时发送到多个队列的场景,例如 “系统通知”“数据同步”。示例: 交换机绑定 Q1、Q2、Q3,无论消息的 Routing Key 是什么,这三个队列都会收到消息。3. Topic(主题交换机)路由规则:通过 Routing Key 和 Binding Key 的模糊匹配路由消息,支持通配符:*:匹配一个单词(以 . 分隔的字符串,例如 order.* 匹配 order.create,但不匹配 order.create.detail)。#:匹配零个或多个单词(例如 order.# 匹配 order、order.create、order.create.detail)。适用场景:需要按 “主题” 分类路由的场景,例如 “日志按级别和模块过滤”“订单按类型和状态过滤”。示例: 队列 Q1 绑定 Binding Key = "log.#",则 Routing Key 为 log.error、log.info.db 的消息都会被路由到 Q1; 队列 Q2 绑定 Binding Key = "log.*.db",则仅 log.error.db 会被路由到 Q2(log.db 不匹配,因为 * 需匹配一个单词)。4. Headers(头交换机)路由规则:不依赖 Routing Key,而是通过消息的 headers 属性(键值对)与队列绑定的 headers 进行匹配。匹配规则由 x-match 决定:x-match = "any":消息 headers 与绑定 headers 有至少一个键值对匹配即可。x-match = "all":消息 headers 与绑定 headers 的所有键值对完全匹配。特点:灵活性高,但性能略低于其他类型(需解析 headers),实际使用较少。适用场景:需要基于多条件复杂路由的场景(较少见,通常可用 topic 替代)。示例: 队列绑定 headers = {"type": "order", "status": "paid"} 且 x-match = "all",则只有消息 headers 同时包含这两个键值对时才会被路由。总结:核心区别对比交换机类型路由依据匹配规则典型场景性能DirectRouting Key = Binding Key精确匹配单一分类消息(如错误日志)高Fanout无(忽略键)广播到所有绑定队列群发通知、数据同步最高TopicRouting Key + 通配符*(单单词)、#(多单词)按主题分类(如多模块日志)中Headers消息 headers 属性键值对匹配(any/all)复杂多条件路由(少见)较低实际开发中,direct(精确路由)和 topic(模糊路由)最常用,fanout 适合广播场景,headers 因使用复杂较少推荐。
-
前言RocketMQ与Kafka 是我们最常用的消息中间件,那么它们之间有什么区别呢?本文带你一起来研究下这个问题!首先,淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成本,我们认为存储部分可以进一步优化,2011年初,Linkin开源了Kafka这个优秀的消息中间件,淘宝中间件团队在对Kafka做过充分Review之后,Kafka无限消息堆积,高效的持久化速度吸引了我们,但是同时发现这个消息系统主要定位于日志传输,对于使用在淘宝交易、订单、充值等场景下还有诸多特性不满足,为此我们重新用Java语言编写了RocketMQ,定位于非日志的可靠消息传输(日志场景也OK),目前RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。数据可靠性RocketMQ支持异步实时刷盘,同步刷盘,同步Replication,异步ReplicationKafka使用异步刷盘方式,异步Replication总结:RocketMQ的同步刷盘在单机可靠性上比Kafka更高,不会因为操作系统Crash,导致数据丢失。同时同步Replication也比Kafka异步Replication更可靠,数据完全无单点。另外Kafka的Replication以topic为单位,支持主机宕机,备机自动切换,但是这里有个问题,由于是异步Replication,那么切换后会有数据丢失,同时Leader如果重启后,会与已经存在的Leader产生数据冲突。开源版本的RocketMQ不支持Master宕机,Slave自动切换为Master,阿里云版本的RocketMQ支持自动切换特性。性能对比Kafka单机写入TPS约在百万条/秒,消息大小10个字节RocketMQ单机写入TPS单实例约7万条/秒,单机部署3个Broker,可以跑到最高12万条/秒,消息大小10个字节总结:Kafka的TPS跑到单机百万,主要是由于Producer端将多个小消息合并,批量发向Broker。RocketMQ为什么没有这么做?Producer通常使用Java语言,缓存过多消息,GC是个很严重的问题Producer调用发送消息接口,消息未发送到Broker,向业务返回成功,此时Producer宕机,会导致消息丢失,业务出错Producer通常为分布式系统,且每台机器都是多线程发送,我们认为线上的系统单个Producer每秒产生的数据量有限,不可能上万。缓存的功能完全可以由上层业务完成。单机支持队列Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长RocketMQ单机支持最高5万个队列,Load不会发生明显变化队列多有什么好处?单机可以创建更多Topic,因为每个Topic都是由一批队列组成Consumer的集群规模和队列数成正比,队列越多,Consumer集群可以越大消息投递实时性Kafka使用短轮询方式,实时性取决于轮询间隔时间RocketMQ使用长轮询,同Push方式实时性一致,消息的投递延时通常在几个毫秒。消息失败重试Kafka消费失败不支持重试RocketMQ消费失败支持定时重试,每次重试间隔时间顺延总结:例如充值类应用,当前时刻调用运营商网关,充值失败,可能是对方压力过多,稍后在调用就会成功,如支付宝到银行扣款也是类似需求。这里的重试需要可靠的重试,即失败重试的消息不因为Consumer宕机导致丢失。更多面试题推荐:公众号Java精选,回复java面试,获取最新面试资料。严格的消息顺序Kafka支持消息顺序,但是一台Broker宕机后,就会产生消息乱序RocketMQ支持严格的消息顺序,在顺序消息场景下,一台Broker宕机后,发送消息会失败,但是不会乱序Mysql Binlog分发需要严格的消息顺序定时消息Kafka不支持定时消息RocketMQ支持两类定时消息开源版本RocketMQ仅支持定时Level阿里云ONS支持定时Level,以及指定的毫秒级别的延时时间分布式事务消息Kafka不支持分布式事务消息阿里云ONS支持分布式定时消息,未来开源版本的RocketMQ也有计划支持分布式事务消息消息查询Kafka不支持消息查询RocketMQ支持根据Message Id查询消息,也支持根据消息内容查询消息(发送消息时指定一个Message Key,任意字符串,例如指定为订单Id)总结:消息查询对于定位消息丢失问题非常有帮助,例如某个订单处理失败,是消息没收到还是收到处理出错了。推荐程序员摸鱼地址:https://www.yoodb.com/slack-off/home.html消息回溯Kafka理论上可以按照Offset来回溯消息RocketMQ支持按照时间来回溯消息,精度毫秒,例如从一天之前的某时某分某秒开始重新消费消息总结:典型业务场景如consumer做订单分析,但是由于程序逻辑或者依赖的系统发生故障等原因,导致今天消费的消息全部无效,需要重新从昨天零点开始消费,那么以时间为起点的消息重放功能对于业务非常有帮助。消息并行度Kafka的消费并行度依赖Topic配置的分区数,如分区数为10,那么最多10台机器来并行消费(每台机器只能开启一个线程),或者一台机器消费(10个线程并行消费)。即消费并行度和分区数一致。RocketMQ消费并行度分两种情况顺序消费方式并行度同Kafka完全一致乱序方式并行度取决于Consumer的线程数,如Topic配置10个队列,10台机器消费,每台机器100个线程,那么并行度为1000。消息轨迹Kafka不支持消息轨迹阿里云ONS支持消息轨迹开发语言友好度Kafka采用Scala编写RocketMQ采用Java语言编写Broker端消息过滤Kafka不支持Broker端的消息过滤RocketMQ支持两种Broker端消息过滤方式根据Message Tag来过滤,相当于子topic概念向服务器上传一段Java代码,可以对消息做任意形式的过滤,甚至可以做Message Body的过滤拆分。消息堆砌能力理论上Kafka要比RocketMQ的堆积能力更强,不过RocketMQ单机也可以支持亿级的消息堆积能力,我们认为这个堆积能力已经完全可以满足业务需求。开源社区活跃度Kafka社区更新较慢RocketMQ的github社区有250个个人、公司用户登记了联系方式,QQ群超过1000人。商业支持Kafka原开发团队成立新公司,目前暂没有相关产品看到RocketMQ在阿里云上已经开放公测近半年,目前以云服务形式免费供大家商用,并向用户承诺99.99%的可靠性,同时彻底解决了用户自己搭建MQ产品的运维复杂性问题成熟度Kafka在日志领域比较成熟RocketMQ在阿里集团内部有大量的应用在使用,每天都产生海量的消息,并且顺利支持了多次天猫双十一海量消息考验,是数据削峰填谷的利器。
-
828选华为云,实惠更实用!研发与中间件专场全场3折起! Redis、Kafka、数字资产链、软件开发平台,首购低至1.98元! 下单抽FreeBuds耳机,满额送P50手机,助力企业转型云原生2.0! 活动有效期至2022年9月16日,上云正当时!>点击这里,马上进入活动专场<
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签