要求
幂等性
多次执行,结果一致
消费端实现幂等性,就意味着,我们的消息永远不会消费多次,即使我们收到了多条一样的消息
借鉴数据库的乐观锁机制
比如我们执行一条更新库存的SQL语句
UPDATET REPS SET COUNT=COUNT -1,VERSION
VERSION 1 WHERE VERSION=1
唯一ID+指纹码机制,利用数据库主键去重
SELECT COUNT(1)FROM T ORDER WHERE ID=唯一ID+指纹码
好处:实现简单
坏处:高并发下有数据库写入的性能瓶颈
解决方案:跟进D进行分库分表进行算法路由
利用Redis的原子性去实现
如何选择
ActiveMQ
- 由Apache 出品,java开发,支持JMS1.1协议和J2EE 1.4规范
- 支持广泛的连接协议: OpenWire/STOMP/REST/XMPP/AMQP
- 支持多种语言和客户端,支持插件
- 管理方方便,便于集群配置代理
优点
- 基于java,跨平台运行
- 可以使用JDBC连接多种数据库
- 有完善的界面,监控,安全机制
- 自动重连和错误重试
缺点
- 社区活跃度不及RabbitMQ
- 目前重心放到6.0产品Apollo,对5的Bug维护较少
- 不适合用于上千队列的应用场景
RabbitMQ
- 当前最主流的消息中间件
- 高可靠性,支持发送确认,投递确认等特性
- 高可用,支持镜像队列
- 支持插件
优点
- 基于ErLang,支持高并发
- 支持多种平台,多种客户端,文档齐全
- 可靠性高
- 在互联网公司有较大规模的应用,社区活跃度高
缺点
- Erlang语言较为小众,不利于二次开发
- 使用AMQP协议,使用起来有学习成本
- 代理架构下,中央节点增加了延迟,影响性能
- 对积压消息处理的不够好
- 如果有大量的消息积压,性能会下降
- RabbitMQ 的性能是我们介绍的这几个消息队列中最差的,根据官方给出的测试数据综合我们日常使用的经验,依据硬件配置的不同,它大概每秒钟可以处理几万到十几万条消息。其实,这个性能也足够支撑绝大多数的应用场景了,不过,如果你的应用对消息队列的性能要求非常高,那不要选择RabbitMQ。
RocketMQ
- 阿里巴巴团队开发,经受双十一考验
- 能够保证严格的消息顺序
- 亿级消息堆积能力
- 丰富的消息拉去模式
优点
- 基于java,方便二次开发
- 单机支持1万以上持久化队列
- 内存与磁盘都有一份数据,保证性能和高可用
- 开发度较活跃,版本更新很快
- 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,如果你的应用场景很在意响应时延,那应该选择使用 RocketMQ。RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息
缺点
- 客户端种类不多,较成熟的是java级c++
- 没有web管理界面,提供了一个CLI(命令行界面)
- 社区关注度以及成熟度不如RabbitMQ
- 国产消息队列,在国际上不流行,集成和兼容做的不够好
Kafka
- 主要用户大数据方面,日志收集
- LinkedIn开发的分布式的日志提交系统
- 独特的分区特性,适用于大数据系统
- 性能高效,可扩展良好
- 可复制,可容错
优点
- 快
- 原生的分布式系统
- 零拷贝技术,减少IO操作步骤,提高系统的吞吐量
- 快速持久化:可以在O(1)的系统开销下进行消息持久化
- 支持数据批量发送和拉取
缺点
- 单机超过64个队列/分区时,性能明显劣化
- 使用短轮询方式,实时性取决于轮询间隔时间
- 消费失败不支持重试
- 可靠性比较差
总结
- ActiveMQ最 “老”, 老牌,但维护较慢
- RabbitMQ最 “火”, 适合大小公司,各种场景通杀
- RocketMQ最 “猛” 功能强,但考验公司的运维能力
- Kafka最 “强” 支持超大量的数据,但消息可靠性弱
技术选型
- 各个MQ的性能、瓶颈、使用的业务场景
- 集群架构的多样化、扩展性、可用性、可维护性
- 成本问题,公司与团队、根据实际情况进行选择
- 架构师思考,未来的方向、思考点:比别人多想一步即可