news 2026/10/1 20:39:01

从Pulsar看消息中间件架构重构:存算分离与IoT接入实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从Pulsar看消息中间件架构重构:存算分离与IoT接入实践

COSCon'25和Pulsar Developer Day 2025放在同一场地的那天早上,我站在签到处翻着日程表,心里第一反应是:消息队列(MQ)这个被喊了十几年"老技术"的领域,到底还有多少人愿意专门为它跑一趟开发者日?结果开场半小时我就发现自己想岔了。主会场走廊过道全是人,白板上的讨论稿写了又擦、擦了又写,从上午到散场,围着"Pulsar存算分离""Broker无状态扩容""多租户隔离"这些问题聊的人就没断过。

"Make MQ Great Again"这个标语挂在会场最显眼的位置。我第一眼看到的时候觉得好笑,但认真逛了一圈之后理解了——在技术语境里这四个字说的不是口号,而是一个真实存在的行业状态:消息中间件正在经历一轮实打实的架构重构。这篇文章就把这届活动上我听到、看到、并且自己验证过的东西整理出来,包括Pulsar为什么能在这轮讨论里站到C位、它的核心机制到底解决了什么问题,以及我顺手在现场走读的一个物联网端侧场景——STM32环境监测链路怎么跟消息中间件接起来。适合做后端架构选型、搞物联网接入、或者纯粹对MQ技术演进好奇的读者参考。

1. 为什么"重振MQ"成为这届COSCon'25绕不开的话题

先说一个很多人不愿承认的事实:消息中间件这个领域,过去十年里其实没有发生过真正意义上的架构级创新。大家提到MQ,脑子里浮现的无非是几个固定答案——Kafka吞日志很强,RabbitMQ做业务解耦顺手,RocketMQ在金融场景里有口碑。这些结论本身没错,但它们的底层模型都是围绕"分区""队列""消费组"这三个概念转,转来转去,运维上的老问题一个都没少。

1.1 消息队列的"老问题清单"

我在会场上随手记下了几个高频吐槽点,基本就是当前主流选型的真实痛点:

  • 分区扩容要迁移数据。Kafka的分区一旦定了,想加分区、换Broker、挪副本,都要触发数据重平衡,集群越大,重平衡越痛苦。
  • Broker和存储绑死。传统模型里每个Broker节点自己扛磁盘,想扩容量得加节点,加了节点又得做数据再分布,存储和计算没法各自伸缩。
  • 租户隔离靠"拆集群"。很多团队为了隔离不同业务,直接物理拆出好几套集群,运维成本直接翻倍。
  • 消费模型单一。队列模型和流模型的边界很模糊,一个Topic想既给流处理用、又给业务队列用,配置起来经常别扭。

这些问题单独拎出来任何一个,大家都能忍。但攒在一起,就变成了一个很尴尬的局面:中间件成了分布式系统里最不好伺候的那一块。而这正是Pulsar这类"云原生架构"的中间件能在这届活动现场被反复讨论的根本原因。

1.2 从现场观众构成看MQ需求的三个方向

我在现场观察到一个很有意思的现象:来听Pulsar议题的人,明显分成了三个群体,需求完全不一样。

第一个群体是互联网公司的后端架构师,他们关心的是"我能不能把Kafka迁到Pulsar,省掉分区重平衡的运维噩梦";第二个群体是做SaaS和B端系统的团队,他们关心的是"一个集群能不能同时服务几十个客户,并且互相不干扰";第三个群体最让我意外——不少做物联网和硬件接入的人。他们的问题集中在"设备上报的数据量不大但连接数很多,消息中间件能不能扛得住"。

这三个群体对应的是MQ选型的三个真实驱动力:运维复杂度、多租户隔离、海量连接。而这三点恰恰是Pulsar在架构设计上优先解决的问题。所以与其说Pulsar是来"取代谁"的,不如说它是来回答一个更根本的问题:消息中间件能不能真正做到按需伸缩、自带隔离、原生支持多种接入协议。这届活动上所有的技术分享,基本都围绕这个核心在场内外展开。

2. Pulsar在开发者日上被反复论证的四个硬核点

接下来这部分是我认为整场活动信息密度最高的地方。Pulsar的技术分享不少见,但开发者日的优势在于,讲师会直接放生产环境的实测数据,而不是只讲PPT。我挑四个讨论最热烈的机制来说,每一个都在现场被追问到了底层。

2.1 存算分离:把"仓库"和"调度中心"分开

Pulsar架构里最核心、也最容易被误解的就是存算分离。用大白话解释:传统Kafka是"运输队和仓库绑在一起"——每个Broker既管接收数据,又管把数据写在本地磁盘,车队要扩大,必须先盖仓库;而Pulsar把这两件事拆开了,Broker只负责接收请求、维护元数据、分发消息,数据本身交给另一层叫BookKeeper的存储节点去持久化。

这意味着什么呢?第一,Broker可以做到真正的无状态,想加就加,想减就减,不需要迁移任何数据。第二,存储层扩容极其简单——往BookKeeper里加Bookie节点就行,新数据会自然分布到新节点上,旧数据不需要大规模重分布。第三,资源可以独立调配:计算压力大就加Broker,存储不够就加Bookie,互不拖累。

当时有个参会者问了一个很尖锐的问题:存算分离之后,一条消息从发给Broker到真正落盘,路径变长了,延迟是不是会变差?讲师直接放了一组数据:Pulsar的端到端延迟(P99)在生产环境可以稳定维持在几十毫秒级别,对于大部分业务消息场景完全是可接受的,而且由于BookKeeper是追加写的日志模型,顺序写盘效率反而很高。也就是说,你用架构上的"多一跳",换来了巨大的运维灵活性,这笔账是划算的。

2.2 多租户隔离与统一配额管理

第二个被反复讨论的是Pulsar的多租户模型。它把资源分成了三级:租户(Tenant)、命名空间(Namespace)、主题(Topic)。租户对应一个业务线或一个客户,命名空间对应一个项目或环境,主题就是具体的数据通道。

这套模型的实际价值在于:一个集群可以同时服务多个业务线,互不干扰,还能做到真正意义上的配额隔离。比如你给A租户配了100GB存储配额和每秒10万条的消息速率限制,给B租户配了10GB和每秒1万条,这两个租户的Topic可以物理上落在同一批Bookie上,但谁也别想抢谁的资源。

现场有做SaaS的工程师分享了一个很典型的例子:他们一个集群收了三十多个客户的流量,每个客户一个租户,通过命名空间区分生产环境和测试环境。遇到某个客户突发流量,直接给对应租户调配额就行,其他客户完全无感。这个能力在传统MQ里几乎是不可想象的——以前要么拆集群,要么被"噪音邻居"问题折磨。多租户这个特性,对任何需要面向多业务方提供消息能力的团队来说,都是实打实的降本手段。

2.3 四种订阅模型与消费模式的组合

Pulsar在消费模型上的设计也是现场讨论的热点。它把"订阅"和"消费"分开理解,四种订阅类型覆盖了几乎所有消息场景:

  • 独占订阅(Exclusive):一个Topic同一时刻只允许一个消费者,适合严格有序处理的场景。
  • 共享订阅(Shared):多个消费者轮询拉取消息,适合吞吐优先、不需要严格顺序的任务队列。
  • 键共享订阅(Key_Shared):按消息Key把消息路由到固定的消费者,同一Key的消息有序,不同Key的可并行,这是非常实用的折中方案。
  • 故障转移订阅(Failover):多个消费者绑定一个Topic,主消费者挂了自动切到备用的,适合需要高可用但不想牺牲顺序的场合。

我当时就想,要是早几年有这个模型,很多团队就不用为了"既要顺序又要并行"这种需求去自研一层路由了。这四种订阅类型和Pulsar的多租户能力结合起来,基本可以覆盖从流处理到业务解耦的绝大多数场景。

2.4 跨地域复制与容灾的实操意义

活动上还有一个话题让我印象很深:跨地域复制。Pulsar原生支持多个集群之间的异步复制,消息在本地集群写入后,会异步同步到远端集群。这跟我们常见的"主备切换"不同,它是双向的、多活的结构,每个集群都是独立的生产和消费入口,数据在多个地域之间互相复制。

对一个有容灾要求的系统来说,这个能力意味着:你的消息中间件不需要再单独搭一套复杂的数据同步工具,配置几行就能建立跨地域的数据通道。现场有个做金融支付场景的工程师分享,他们用Pulsar的双集群复制做机房级容灾,数据损失窗口控制在秒级,切换时几乎无感知。当然,跨地域复制有个前提是网络质量要好,这个我们在国内的云环境下基本都是满足的。

3. 当MQ真正下沉到硬件:一个STM32环境监测链路的现场走读

说实话,我的关注点本来只在服务端架构上,但这次活动有个环节很特别——现场摆了一个用STM32做环境监测的端到端demo,从传感器采集到消息中间件再到云端展示全链路打通。当时围了一圈人,我挤进去看完之后发现,这其实就是把消息队列用在物联网场景最好的教学案例。

3.1 从MQ-2到MQ:一个有趣的名字插曲

先说个现场的乌龙。有人看到demo板上的气体传感器写着"MQ-2",第一反应是"这怎么还跟消息队列同名了",还专门回头去确认自己没走错会场。其实这里的MQ是英文"气体敏感材料"相关命名的历史遗留叫法,跟消息队列Message Queue的缩写完全就是一个巧合。但这正好成了一个很生动的隐喻:硬件端的传感器在采集数据,软件端的消息队列在搬运数据,两个"MQ"在一条链路上碰了面。这届活动的标题叫"Make MQ Great Again",某种程度上也像是给这两个"MQ"一起喊的话。

3.2 端侧采集的完整链路

我把那个demo的硬件链路拆开整理了一下,完全复刻成本不高,物料都很便宜,适合拿来练手。主要模块包括:

  • STM32F103C8T6主控板,或者带WiFi的ESP32也可以,看你想不想让设备直接联网。
  • DHT11温湿度传感器,用的单总线协议,读取时序要卡准,数据脚接普通GPIO。
  • BH1750光照传感器,走I2C总线,分辨率可以到1勒克斯,量程覆盖1到65535。
  • MQ-2气体传感器,输出是模拟量,用ADC采样,上电后需要预热一会儿再读数值。
  • OLED屏,通常是SSD1306驱动,I2C接口,用来本地显示读数。

采集逻辑不复杂,我整理成大概这样的流程:

while (1) { 定时1秒: 读DHT11 -> 温度 + 湿度 读BH1750 -> 光照强度 读MQ-2(ADC多次采样取均值) -> 气体浓度标定值 OLED刷新显示 MQTT发布:{"temp":26.5,"humidity":48.0,"light":320,"gas":0.21} delay(1000); }

实际做的时候有几个小坑:DHT11的读到一半总线就被拉低会卡死,最好加超时退出;BH1750有几种测量模式,连续高分辨率模式适合做监测;MQ-2的模拟值受供电电压影响,建议用稳定3.3V或5V供电,并且记录基线值做相对比较,而不是直接拿绝对值当标准浓度。

3.3 为什么IoT数据值得走消息中间件而非HTTP直连

这个demo真正有意思的地方,不是采集本身,而是数据传输环节的设计逻辑。很多做硬件原型的人第一反应是"设备直接HTTP POST到服务器",但当设备量上来以后,HTTP直连的坑会越来越明显。

设备端到服务器之间加一层消息中间件,解决的是三个很实际的痛:第一,连接不是短命的一次性请求,而是长连接,设备状态可以被服务端实时感知;第二,数据先落到Topic里,消费端按自己的节奏拉取,服务器临时抖动也不会丢数据;第三,多个来源的数据可以在同一个集群里统一处理,比如环境监测数据、设备心跳、告警事件全部进入Pulsar,再按租户和命名空间分类,后期无论是写库还是触发告警,都有清晰的通道。

现场这个demo用的是MQTT协议从传感器接入,然后通过Pulsar的MQTT协议适配能力直接进入Topic,后续有订阅者负责把数据写入时序数据库做展示。这套链路的优雅之处在于:你完全不需要为物联网场景单独建一套后端,消息中间件天然就把"设备接入"和"业务处理"解耦了。

4. 围观之后要想清楚的三件事:避坑经验与选型复盘

参加完活动,最值钱的其实不是"Pulsar好棒"这种结论,而是搞清楚"它到底好在哪,以及哪些场景不应该用"。我在现场和一些已经落地Pulsar的工程师聊完,加上回去后自己做了几天压测和部署测试,整理出三条最容易犯的认知偏差。

4.1 误区一:Pulsar只能跑在K8s上

活动上有人一听到云原生就默认必须上K8s,这个想法其实是把云原生和容器编排绑定死了。Pulsar确实在K8s里有官方Operator,部署很丝滑,但对于中小团队来说,用Docker Compose在几台裸机上跑一个最小集群也完全可行,甚至搭配二进制包直接部署都能跑得很稳。

我实测下来,单机部署Pulsar做功能验证非常快,跑起来只需要一个ZooKeeper(或自带的元数据服务)、一个Broker、一个Bookie。真正要注意的是生产环境的存储规划:BookKeeper的Journal盘和Ledger盘要分开,Journal盘用SSD,Ledger盘可以用机械盘做低成本的大容量存储。这种配置细节比纠结"用不用K8s"重要得多。

提示:最小可用集群跑通之后,再考虑到底要不要K8s。很多团队的生产流量其实还没大到需要弹性扩容,先把JVM内存参数、磁盘规划、监控告警这些基础做好,收益更大。

4.2 误区二:存算分离只是"Kafka加外部存储"

这是在会上被讲师正面纠正过的理解。存算分离不是把Kafka的消息搬到对象存储里就叫分离,关键是两个方向的独立弹性:Broker不持有任何数据,扩容时不需要数据迁移;BookKeeper以追加日志的方式提供高吞吐持久化,数据保留策略、副本策略都由存储层统一管理。

所以你会发现一个很实际的效果:当你需要增加Topic或调整保留时间时,Pulsar的操作是秒级的,你不需要关心数据被存到了哪台机器、磁盘够不够、要不要重平衡。这在Kafka里是好几件事,在Pulsar里是一件事。真正的价值不是"架构上很酷",而是日常运维里省下的那无数个小时。

4.3 误区三:多租户是大型团队才会用到的东西

我一开始也觉得,自己团队就一个业务线,要啥租户隔离。但仔细想一下:开发环境、测试环境、生产环境,是不是就是三个天然隔离的空间?在Pulsar里,把它们放进三个命名空间,甚至分属不同租户,你就能对每个环境设置独立的保留策略、存储配额和权限控制。开发环境产生的垃圾Topic不会污染生产,测试环境的流量再大也卡不到生产数据——这就是多租户的最小落地场景。

4.4 一张选型表与一个冷静的边界

综合这届活动上的讨论,我把几个主流的消息中间件做成一张对照表,方便做选型时直接参考:

维度RabbitMQApache KafkaApache RocketMQApache Pulsar
核心定位企业级消息路由高吞吐流数据管道金融级可靠消息云原生流与队列一体化
吞吐量级万级百万级十万级百万级
消息模型队列为主分区+消费组Topic+队列Topic+订阅
多租户隔离弱,靠拆实例弱,靠Topic约定中原生三级隔离
数据保留短,消费即删按磁盘大小保留按时间保留按策略精细化控制
扩容体验加节点加节点+重平衡加节点+迁移计算/存储独立加
适合场景异步解耦、任务分发日志、实时数仓事务消息、订单混合负载、IoT多租户接入

选型时最关键的一条边界是:流量很小、业务简单、团队运维时间有限的场景,别盲目上Pulsar。它再能打,也需要你理解BookKeeper、懂存储规划、能配置租户策略。如果你的需求就是"几十个微服务之间发个异步消息",RabbitMQ的那点运维成本反而更低。技术选型从来不是选最先进的,而是选最匹配你当前复杂度的。

活动散场时我在门口站了一会儿,几个参会者还在聊Pulsar与Kafka的迁移对比。回想这届COSCon'25和Pulsar Developer Day,给我留下最深印象的不是具体某个功能点,而是大家终于开始认真讨论"消息中间件应该长成什么样子"这个问题本身。从现场那个把STM32传感器接入消息队列的demo,到多租户隔离在生产环境的真实分享,其实都在说明一件事:MQ这个"老家伙"并没有过时,它只是在换一种更符合云时代和物联网时代需求的方式存在。如果你正在纠结消息中间件选型,我的建议很简单——先把流量模型算清楚,再把团队能付出的运维精力算清楚,然后带着这两个数字重新回去看一遍这些对比,答案会比你想的明显很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 20:38:34

SpringBoot+SSM宠物店管理系统全解:实现、调试与部署实战

又是一套宠物店管理系统——这类“JavaSpringBootSSM”组合的管理系统,可以说在Java后端项目里出现频率相当高。不管是毕业设计、课程实训,还是宠物店老板真正想搞一套能跑起来的管理软件,它都能满足:登录权限、档案管理、会员消费…

作者头像 李华
网站建设 2026/10/1 20:35:21

ESP32端侧AI硬件的8大工程落地难题与实战解法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 20:35:05

免解压一键部署,Codex Harness 本地 AI 自动化办公落地教程

✨前言 相比手动安装 Node.js、再敲命令行,一键安装包将环境配置、依赖安装与客户端部署一并打包,省去了繁琐的搭建步骤,非常适合不想折腾、希望快速上手的用户。全程只需按提示操作,几分钟内即可开始使用。 📥一、下…

作者头像 李华
网站建设 2026/10/1 20:34:43

深度拆解 Claude Code AskUserQuestion:AI 交互式提问工具精妙设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华