服务之间如果全部走同步调用,某个环节一慢,整条链路都会跟着卡住。消息队列就是为了解决这类问题。阿里云上并没有一个名为”阿里云队列”的单一产品,这个说法通常指云上的消息队列类服务,比如 RocketMQ 版、Kafka 版,或者 MNS 提供的队列模型。具体用哪个,要看控制台里的产品规格和业务需求,不过基本思路大体相通。

队列解决的是什么问题
队列的核心作用是把”发出请求”和”处理请求”拆开。生产者把消息写进队列就可以返回,消费者按自己的速度拉取处理。大促时流量突然涨上来,消息会先排在队列里,下游慢慢消化,而不是直接把库存服务或数据库压垮。这就是常说的削峰填谷。同时,生产方不再需要知道下游有哪些系统,新增一个消费者不影响上游代码,这就是系统解耦。
使用云上队列的好处是,服务端的高可用、数据持久化和扩容由云厂商负责,团队主要精力放在消息怎么生产、怎么消费上。不过托管服务不等于零维护,消费逻辑写得不好,照样会出问题。
上线前要自己设计的几个点
有几项能力在选型时要看清楚,但真正落地时,很多要靠业务代码补齐。
- 消息持久化要确认产品是否把消息落盘并保留足够时长。如果消费端挂了几个小时,消息还在不在,这一点要提前验证。
- 顺序消费对订单这类状态流转很重要。订单从”待支付”到”已支付”再到”已发货”,如果乱序处理,结果可能是已发货的订单又被改回待支付。这类业务要用同一个订单号作为分区键,保证同一对象的消息进入同一分区。
- 重试与死信要设置最大重试次数,超过后转入死信队列。死信不能只是堆在那里,要有人定期查看,并且有明确的补偿动作。
- 消费幂等很关键,因为网络抖动或超时重试都可能造成重复投递。消费前先用业务唯一 ID 查一次处理记录,或者用数据库唯一索引兜底,避免同一笔扣款被处理两次。
- 监控指标重点盯三个数字,分别是堆积量、消费延迟和失败率。堆积量持续上涨,通常说明消费能力跟不上,而不是偶发抖动。
几个常见的使用场景
大促时的下单链路
订单服务完成基础校验并生成订单后,把”订单创建成功”事件写入队列就直接返回。库存扣减、积分发放、短信通知由各自的消费者处理。这样即使积分服务短时间变慢,下单接口也不会跟着超时。不过库存扣减通常仍要同步校验,不能简单全部异步化,否则会出现超卖。哪些环节能异步,要和业务方一起确认。
业务数据同步到分析平台
业务库的数据变更可以作为事件投递到队列,由独立的程序批量写入数据仓库。分析任务不再直接查询业务库,线上库的查询压力会小很多,两边的表结构和处理节奏也能独立调整。
视频上传后的异步处理
用户上传视频后,转码、截图、内容审核都比较耗时。前端提示”处理中”,任务由工作节点从队列中取出执行,完成后通过站内消息或回调通知用户。这类任务单个耗时长、失败概率也高,很适合放在队列里,失败后可以按策略重试。
消息堆积了怎么办
堆积出现时,先不要急着扩容。先判断是哪一段出了问题:生产速度突然变快,还是消费速度变慢。两者处理方式完全不同。
- 先看消费延迟的变化曲线。如果是某个时间点开始突然堆积,先查这个时间点前后有没有发版、有没有下游接口超时。很多时候堆积是某次变更引起的,回滚比扩容更快。
- 再检查消费逻辑本身。看消费者里是否有慢 SQL、同步调用了响应很慢的外部接口,或者日志里大量报错重试。这些问题不解决,加机器也只是把瓶颈往后推。
- 扩容消费者前先确认分区数。同一分区通常只能被一个消费者实例消费,实例数超过分区数并不会提升并行度。扩容前先确认分区或队列数量是否足够。
- 必要时暂停或限流非核心生产方。如果堆积已经影响核心链路,可以先暂停日志、推荐等非关键消息的发送,给核心消息腾出处理能力。
- 控制重试风暴。下游恢复后,大量失败消息同时重试容易再次压垮下游。重试之间应加上退避时间,并限制单位时间内的重试量。
- 堆积消化后做补偿核对。对比关键业务的数据,确认没有漏处理或重复处理的记录,死信里的消息也要逐条确认。
落地前的几点提醒
- 先划清同步和异步的边界。涉及资金、库存这类强一致操作,要明确哪些步骤必须同步完成,不要为了异步而异步。
- 消息结构要预留字段。消息体里放上事件类型、业务主键、发生时间和版本号。后面改动消息格式时,老消费者能识别旧版本,不会直接报错。
- 上线前做一次压测。按峰值流量估算分区数和消费者实例数,模拟消费端变慢的情况,观察堆积后的恢复速度是否在可接受范围内。
- 小范围先跑一段时间。先接入一条非核心链路,观察监控和死信情况,确认没问题后再推广到主流程。
队列本身不会自动解决性能问题。它能把压力摊开、把依赖拆开,但消费逻辑、幂等设计和监控告警还是要团队自己做好。把这些基础打牢,异步架构才会真正稳定下来。