日常学习笔记

学习笔记

消息队列

1、消息队列的作用及对比

消息队列主要用到的为rabbitMQ,RocketMQ以及kafka,其中rabbitMQ是用erlang编写的比较稳定的MQ,但是不容易深入去掌握;RocketMQ是阿里出品的稳定MQ,但是目前社区不活跃;kafka主要用于大数据领域以及记录日志,可用性非常高。

2、消息队列的作用

  1. 解耦:作为中间层灵活的配置生产者和消费者
  2. 异步:将某些耗时请求异步处理
  3. 削峰:应对突然某个时段的高并发访问

缺点:降低了系统的可用性,提高了系统的复杂性,以及存在信息一致性的问题。

3、如何保证消息队列的可用性

  1. rabbitMQ:

本质为传统的消息队列。

通过镜像集群模式,每个MQ的节点都对所有的queue数据进行备份同步。

缺点:性能开销大,没法线性扩展。

  1. Kafka:

天然的分布式消息队列。

0.8版本以后,集群维护一个主从模式,每组partition会选出一个节点作为leader,每次外界的读写操作都只能与leader节点对接,然后再同步到所有的节点。如果leader节点挂了,followers会重新选出一个leader节点。

4、如何保证消息队列不会重复消费

  1. 问题:

Kafka有个offset作为消息的序号,每次consumer消费了数据之后,每隔一段时间会将offset提交表示已经消费过了。但如果这是系统kill进程重启,会使得consumer来不及提交offset,重启后就会造成重复消费。

  1. 幂等性:

一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错

  1. 如何保证幂等性:

比如数据库加主键或者唯一索引;

或者利用一条全局id,如订单id,每次要消费时去redis里查一下,没有就消费,有则不处理。

5、如何保证消息队列不会丢失消息

  1. RabbitMQ:

生产者端:

1、开启事务模式,同步操作,提交一个操作会阻塞在那,传输失败则回滚,会造成资源极大的消耗。

2、开启confirm模式,异步操作,每次写消息会分配一个唯一的id,如果传输成功,MQ会回复一个ack消息,如果失败会回复传输失败。

MQ端:

设置持久化,要将queue和消息都持久化。

消费者端:

关闭自动ack机制,在消费者处理完后自行发送ack给MQ。

  1. Kafka:

消费者端:

关闭自动offset机制,在消费者处理完后自行发送offset给kafka。

Kafka端:

当某个leader挂了时,需要重新选举leader,此时会丢失一些数据未同步。

此时需要通过参数设置,让leader与followers保持联系,确保partitions存在副本等,保证leader切换时不会发生数据丢失。

生产者端:

设置ack=all,即你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了,否则无限重试,则一定不会丢失数据。

6、如何保证消息队列顺序性

  1. RabbitMQ:

一个queue对应一个consumer,consumer内部用内存队列做排队。

  1. Kafka:

每个key对应一个内存队列,保证顺序性。

7、消息队列消费端出问题如何解决

  1. 大量消息积压在mq:

如果消费端如MySQL挂了,会有很多消息积压在mq中,此时应该先修复消费端的问题,然后进行临时扩容去快速消费mq中的消息。

  1. Mq中的消息过期:

在低峰期手动将消息找出来重新消费。

  1. Mq积压快满了:

写临时程序来丢弃消息,再在低峰期时手动将消息找回来重新消费。

8、如何自行设计一个消息队列

  1. 首先需支持可升缩性,需要时可以快速扩容
  2. 考虑数据持久化方式,顺序落磁盘
  3. 高可用性,可以参考kafka的leader-follower方案
  4. 数据0丢失,参考kafka的机制
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值