阿里云多种消息服务的差异及选型
阿里云消息服务现状
目前阿里云提供多种消息队列服务:
这里我们只关注笔者目前使用的两个消息队列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接入成本
- 增加消息跟踪,支持生产者、消费者两端的消息状态查询
- 增加消息重放,在消息跟踪的基础上实现