阿里云多种消息服务的差异及选型

背景:消息中间件日益在应用系统中必不可少,阿里云提供多种消息MessageQueue服务,有历史原因也有产品线不统一或尽可能提供用户更多选择的原因。笔者根据实际使用,总结下阿里云消息服务的历史、不同消息服务的差异、最后给出推荐选用原则。

阿里云消息服务现状

目前阿里云提供多种消息队列服务:

这里我们只关注笔者目前使用的两个消息队列Message Queue中间件:

  • 消息服务MNS
  • 消息队列RocketMQ

阿里云消息服务MNS和RocketMQ的历史

消息服务MNS

原名MQS,阿里在2012年立项自研项目,2014年阿里云上线公测,2015年改名MNS服务,最后更新时间为2015年12月。

从历史可以看到MNS消息队列从最早12年立项自研,历经MQS改名为MNS,15年后稳定提供云服务。

笔者从16年接触使用MNS,到目前仍有100+队列线上运行,从实际使用情况看,总结如下:

  • 稳定性:三年未发生过大的事故,除了某次阿里云机房故障,各云服务均受影响
  • 可靠性:线上未发生消息丢失,多方对账验证也未发现
  • 顺序性:不保证消息有序,虽然提供Python版的内存排序方案,但无法保证严格有序
  • 价格:非常便宜,2元/百万次,几乎相当于不要钱了
  • 不足:监控、报警由于不开放API,只能依赖阿里云的云监控,收费项目

消息队列RocketMQ

阿里借鉴Kafka设计思想,并优化低延迟、高可靠性方案,研发出来内部高性能、高可靠、功能完备的RocketMQ,同时提供开源和云服务。

消息队列 RocketMQ 是阿里巴巴集团自主研发的专业消息中间件,基于高可用分布式集群技术,提供消息订阅和发布、消息轨迹查询以及定时(延时)消息、资源统计、监控报警等一系列消息云服务,是企业级互联网架构的核心产品。 消息队列 RocketMQ 历史超过9年,为分布式应用系统提供异步解耦、削峰填谷的能力,同时具备海量消息堆积、高吞吐、可靠重试等互联网应用所需的特性,是阿里巴巴双11使用的核心产品。

主要特性:

  • 消息类型:普通消息、定时/延时消息、顺序消息、事务消息
  • 消息Exactly-Once 投递,此特性仅支持Java SDK
  • 顺序消息:云服务RocketMQ支持全局有序和分区有序
    • 全局有序这个太厉害了,目前开源实现版本貌似不支持
  • 支持消息回溯
  • 支持消息轨迹(消息状态跟踪)

注意事项:

  • 消息重复无法避免,业务上应根据唯一Key来做幂等性处理
    • 发送时消息重复:发送过程网络或Client异常,重试则消息重复
    • 投递时消息重复:接收过程网络或Client异常,为保证At Least Once,重试则消息重复
    • 负载均衡时消息重复:Broker重启、扩容、缩容,触发消息Rebalance,可能消息重复
  • MessageId不保证全局唯一,业务上应设置MessageKey来保证唯一性
  • TCP版SDK仅支持Java、C/C++、.NET,不支持PHP/Go/Python等语言
  • HTTP版SDK支持Go/Python/Nodejs/PHP/Java/C++/C#
  • RocketMQ未支持优先级队列

消息队列 AMQP(RabbitMQ)

消息队列 AMQP 由阿里云基于 AMQP 标准协议研发,完全兼容 RabbitMQ 开源生态以及多语言客户端,打造分布式、高吞吐、低延迟、高可扩展的云消息服务。开箱即用,用户无需部署免运维,轻松实现快速上云,阿里云提供全托管服务,更专业、更可靠、更安全。

特性及注意事项:

  • 定时消息:开源版RabbitMQ不支持
  • 死信队列
  • 完全兼容 AMQP 标准协议和 RabbitMQ 开源生态
  • 目前阿里云版仅提供Java版SDK

云服务:MNS和ONS中消息队列RocketMQ的对比


引用阿里中间件团队的RocketMQ、RabbitMQ、Kafka同步发送性能对比:Kafka > RocketMQ > RabbitMQ

推荐选用原则

分析业务实际需求、潜在需求,对消息系统的功能性要求有哪些,主要考虑的特性:

特性 RocketMQ MNS RabbitMQ
有序性 全局有序+分区有序 Client内存排序 单Producer+同Exchange/Queue+单消费Channel可保证有序
可靠性
拉取模式 Pull/Push Pull/Push Pull/Push
发送性能 1万 3000 1万
优先级队列 不支持 支持 支持
延时队列 支持 支持 非原生支持
价格 普通:2元/百万次API请求;事务/顺序/定时消息:5倍计费 2元/百万次API请求 同RocketMQ

RabbitMQ非原生支持延时队列,仅支持消息或队列的TTL超时,但无法灵活实现延时策略,rabbitmq-delayed-message-exchange插件支持毫秒级延时队列方案,但对性能等影响应全面评估。

如果在云服务选择的话,建议:

  • 要求顺序性:选择RocketMQ
  • 要求优先级:可用RabbitMQ或MNS
  • 要求发送速度:超过5000,选择RocketMQ;低于2000/s,均可
  • 价格上二者相当,按调用次数或套餐包、Topic使用费计费
  • 注意:使用云服务,则必须使用阿里云的云监控来做监控报警

我们团队目前的选择

  • 团队基于RabbitMQ搭建的消息队列集群服务
    • 由5台4C8G集群组成
    • 开启持久化、队列镜像
    • 性能满足10倍扩容的需求
  • 基于RabbitMQ API和Prometheus增加报警监控
  • 增加多租户配置管理后台,减少接入配置成本
  • 增加SDK降低使用方Client接入成本
  • 增加消息跟踪,支持生产者、消费者两端的消息状态查询
  • 增加消息重放,在消息跟踪的基础上实现

参考文献