消息队列简单总结

为什么使用MQ

解耦

应用场景:A系统需要调用BCD系统,对于后期维护不利,如果有新的系统增加或者减少都需要修改A项目代码;使用MQ直接可以将消息扔到MQ,谁需要使用订阅就可以了;解决项目强耦合。

异步

应用场景:用户端请求的接口耗时较长,使用MQ可以将请求加入队列,耗时较长的操作作为消费者慢慢消费,不会影响用户体验。

削峰

应用场景:抢购等场景,请求量波动较大,瞬时大流量可能压垮DB如mysql造成整个服务无法使用;可以将消息放到MQ,让消费者以一个较高但是还能承受的速率恒定消费消息,不会导致服务不可用

使用MQ有什么好处和坏处

好处

以上

坏处

  • 系统可用性降低
  • 系统复杂度增加
  • 出现一致性问题

部分问题如何解决

可用性解决

  • RabitMQ部署模式:

    • 单节点
    • 普通集群(一个节点存储消息数据,其他节点只存储元数据—伪高可用)
    • 镜像集群(*)所有节点均存储元数据和消息数据,这不是一种分布式解决方案
  • Kafka部署:
    数据会有副本,存储在其他节点,一个节点掉线可以通过其他节点的副本数据访问,数据不会丢失,这是一种分布式解决方案,类似于ES

重复消费

出现场景:消息队列有一个offset来记录当前已经处理的消息编号。如果消费者在拿取消息并且处理完成后还没有通知MQ更新offset时发生消费者重启,下次启动之后MQ会重新把消费过的消息再发送一遍,造成消息重复消费的情况
解决:消费者需要实现幂等性:即多次消费不会影响数据准确,可以使用某种方式存储已经消费国的消息ID,便于查询。

消息丢失

主要了解RabbitMQ

  • 生产者 -> MQ:生产者已发送但是MQ未收到
    解决:
    • 事务机制
    • confirm回调机制(*):生产者实现接口,MQ收到之后会调用生产者接口
  • MQ本身丢失:MQ重启后消息丢失或者消息收到后在内存但没有及时落盘
    解决:开启持久化

  • MQ-> 消费者:消费者开启autoAck后拿取消息未处理即通知MQ增加offset,出现消费者重启
    解决:关闭autoAck,程序逻辑保证处理完成之后再通知MQ。

消息顺序处理

如果有多个消费者或者单个消费者有多线程处理可能导致有先后顺序的消息被乱序处理。
有先后相关性的部分消息分发到同一个queue或者消费者的同一个线程处理

各个现有MQ调研

  • ActiveMQ:成熟解决方案,但是现阶段社区维护不是很活跃。
  • RabbitMQ:基于erlang的消息队列,响应很快,具有很好的后台管理监控界面,社区活跃。但是吞吐量相对较低且是基于erlang开发,较难研究和二次开发
  • RocketMQ:阿里背书,阿里内部有应用,但是会有后期不再维护的风险
  • Kafka:功能简单但是吞吐量很大,适合大数据方向、成为大数据领域标准方案。比较专。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×