消息队列学习记录

参考

为什么要使用消息队列

主要考察应用场景及优缺点

优点

  • 解耦: 不同服务间的调用
  • 异步:不同系统间的调用
  • 消峰:秒杀等场景,平时量不高,但在特定时间会有大量请求的情况,配置基础服务器资源,并引入MQ平滑处理请求,亦节约了成本。

缺点

  • 可用性降低: 依赖于MQ,若MQ异常,将导致业务异常甚至系统崩溃
  • 复杂度提高:需要考虑消息丢失,重复消费等问题
  • 一致性问题:多个队列同时操作,部分消费失败的问题,异步的处理返回给用户是成功

消息队列产品比较

如何根据特点进行取舍

  • ActiveMQ:万级吞吐量,Java开发,时效性ms级,不怎么维护了,已不建议使用
  • RabbitMQ:万级吞吐量,ErLang开发,时效性us级 社区活跃度高,健壮、稳定、易用、跨平台、支持多种语言、文档齐全,对于.net更友好,使用较多;建议中小型项目使用
  • KafKa:十万级吞吐量,Scala/Java开发,时效性ms级,性能卓越,分布式可用性高,性能卓越,被大多数日志,大数据领域使用;消费失败不支持重试,使用短轮询方式,实时性取决于轮询间隔时间,支持消息顺序,但是一台代理宕机后,就会产生消息乱序。日志采集等服务建议使用
  • RocketMQ:十万级吞吐量,Java开发,时效性ms级,可用性非常高,分布式架构,消息可靠性高,支持10亿级别的消息堆积,不会因为堆积导致性能下降;客户端支持不完善,且阿里的云服务linux只支持http模式访问。大型项目建议使用

消息队列的高可用

  • 镜像集群(RabbitMQ):多个节点队列,同步数据,保证数据完整
  • 分布式部署(RocketMQ):使用双主双从,保证都有备份

消息丢失问题

消息丢失的原因

  • 生产者到MQ,发送过程中丢失
  • MQ收到消息,未持久化
  • 消费者渠道消息,未处理成功

如何让消息不丢失

  • 发送消息后应confirm确认
  • 收到消息后持久化
  • 消费者消息处理完毕后手动进行ack确认,确认后mq再删除消息

重复消费问题

  • 无法避免,消费者取到消息后,可能因网络波动无法收到确认状态,这时消息将会再次被消费
  • 消费者应保证消息的幂等性(可以被重复多次消费)
  • 添加全局消息ID,消费时根据消息ID添加状态锁,处理成功后清理锁

消息的顺序性

  • 分段锁,确保同一业务在一个队列,因先进先出的原理,即可保证消费顺序

分布式事务实现

  • 使用本地消息记录消息的消费状态,消费后,回写消息状态,变更本地消息记录表
  • 使用定时任务定时查询本地表消费是否完成,未完成则继续发送消息到MQ,达到最终一致性。
上一篇:Redis 基于 RedisShake 集群迁移


下一篇:redis 版本升级数据迁移使用Redis-Shake