服务之间如果直接同步调用,下游一慢,上游就会跟着卡住,整条链路的响应时间都会被拖长。消息队列把“发消息”和“处理消息”分开:生产方把数据放进队列就能返回,消费方按自己的速度读取。阿里云有好几款消息产品,这篇文章先说明它们分别适合什么场景,再用两个案例看落地时的具体做法。

消息队列主要解决哪些问题
实际项目里,消息队列最常见的用途有三类。
- 削峰填谷:流量突然涌入时,消息先在队列里排着,后端按自己的处理能力匀速消费,服务不会被瞬时请求直接压垮。
- 异步解耦:下单系统只负责写订单,库存、积分、通知等下游服务各自订阅消息。某个下游出问题,下单本身不受影响。
- 可靠传递:消息持久化后,消费方短暂宕机,消息仍在队列里,恢复后可以接着处理。
阿里云消息队列的产品怎么选
阿里云的消息产品覆盖不同协议和业务类型。选型时主要看三点:协议兼容性、消息特性和周边生态。
- 云消息队列 Kafka 版:兼容 Apache Kafka 协议,适合日志采集、流式计算和大数据管道。团队已有的 Kafka 客户端代码可以沿用,改动范围小。
- 云消息队列 RocketMQ 版:支持顺序消息、事务消息和定时消息,适合订单、支付这类交易业务。
- 消息队列 RabbitMQ 版:兼容 AMQP 协议,适合把自建 RabbitMQ 迁到云上的项目。
- 消息服务 MNS:提供简单的队列和主题模型,适合发短信、生成缩略图这类轻量异步任务。
选型前先回答三个问题:团队现有代码依赖哪种协议?业务要求消息有序或事务一致吗?每天大概有多少消息?这三个答案通常能直接指向一款产品。协议已经定了,就按协议选;事务要求高的,先确认 RocketMQ 版能否满足,再考虑其他方案。
案例一:电商大促下单削峰
这是一个简化的典型场景,文中数字为假设值,只用来说明思路。某电商平台日常高峰约每秒 800 笔下单,大促开场时瞬时可能达到每秒 1 万笔。如果订单请求直接打到库存和支付服务上,数据库连接很快会被占满。
团队把下单链路改成消息驱动,主要使用云消息队列 RocketMQ 版:
- 下单接口校验参数后,把订单消息写入 RocketMQ 的订单主题,然后立即返回“排队中”。接口不再等待数据库写入完成。
- 订单服务按数据库能承受的程度设定固定并发,从队列取消息写入订单表。并发数要以压测结果为准,不要凭经验拍一个数。
- 库存扣减使用事务消息,让“扣减库存”和“订单落库”要么同时成功,要么同时回滚。两边只要有一边失败,就不会出现库存多扣或少扣。
- 消费失败超过 3 次的消息进入死信队列,交给人工或补偿任务处理。如果不设上限,一条坏消息会无限重试,持续占用消费能力。
改造后,数据库连接数稳定在平稳区间,大促期间下单接口的响应时间不再随流量一起抬升。用户在高峰期看到的是排队提示,而不是超时报错。排队提示需要前端配合设计,写清楚“请求已受理,可稍后在订单页查看”,否则用户会反复点击,又增加一轮请求。
案例二:应用日志实时写入数据仓库
另一个常见场景是把应用日志送进数据仓库做分析。某企业有几百台服务器,每台都在持续产生访问日志。日志量大、格式杂,如果每台机器都直接写数仓,连接数和写入压力很难控制。
团队选择云消息队列 Kafka 版做日志管道:采集 agent 把日志写入 Kafka 主题,Flink 作业订阅主题,完成字段清洗和聚合后再写入数仓。Kafka 版的分区机制让写入和消费都能水平扩展。新增服务器时,只需增加分区和消费实例,采集端不用改动。
上线前的五个检查点
- 消息体设计:消息里只放业务主键和必要字段。大文件放进对象存储,消息里只带地址。消息体越大,积压时占用的存储和传输成本越高。
- 消费幂等:消息可能被重复投递,消费逻辑要用唯一键去重,确保重复处理的结果一致。上线前可以故意重发一批消息,检查数据会不会重复。
- 重试与死信:先定好最大重试次数和死信处理流程。失败消息如果没人接手,会一直挤占消费能力。
- 堆积监控:给消费延迟和堆积量设告警阈值。堆积持续超过设定时长,立即通知负责人,不要等用户投诉才发现。
- 分区与并发容量:按峰值吞吐反推分区数。压测时同时验证生产端和消费端的上限,只测一端没有意义,下游被打垮的往往是消费端。
常见误区
- 把消息队列当数据库用:历史消息长期堆在队列里,既占资源,排查问题也困难。消息处理完成后,应按保留策略清理。
- 默认所有消息都要有序:只有同一业务实体内的消息需要保证顺序。全局有序会牺牲吞吐,多数场景没有必要。
- 忽略消费端的并发上限:队列能接住消息,不代表下游吃得下。消费端没有限流时,下游服务仍会被打垮。
收尾建议
用消息队列拆开流量高峰和系统耦合,是比较成熟的做法。选型先看协议和消息特性,再看产品名。上线前把幂等、重试和堆积监控做扎实,大多数问题都能在上线前暴露出来。