消息队列的应用场景
-
异步处理,提升吞吐量
-
削峰填谷,平滑流量冲击
-
应用解耦,提升系统可用性
-
消息通讯,点对点消息通讯
消息模型
-
点对点模式
- 生产者生产消息到队列服务器,消费者消费消息,并发送确认收到消息给队列服务器,队列服务器收到确认消息后将消息从服务器删除
-
发布/订阅模式
- 相对点对点模式,引入Topic的概念,队列服务器提供多个Topic供消费者消费,一个消费者消费消息后,其他消费者也能消费到同一条消息(如果不设置ack的话)
如何确保消息不丢失?
-
生产端
- 目标:确保生产的消息能到达MQ服务端
方式:副本数的ack数量、重试多次
缺点:可能会导致消息队列吞吐量下降
- 目标:确保生产的消息能到达MQ服务端
-
服务端
- 目标:确保在分区挂掉时,消息存储不丢失
方式:副本,集群化部署
结果:需要注意非ISR副本不可选举为leader副本
- 目标:确保在分区挂掉时,消息存储不丢失
-
消费端
- 目标:确保消息在消费端不丢失
方式:消费一条,处理一条,手动提交一条offset
结果:消费并处理完消息后,提交offset失败,可能会导致重复消费
- 目标:确保消息在消费端不丢失
如何解决消息重复消费问题?
-
方式一:设置只拉取一次,先提交offest再处理消息,可能会在处理报错后再想消费消息消费不到,所以这种方式一般不采用
-
方式二:允许重复消费,消费端在消费时借助redis或数据表做好幂等性设计
如何保证消息是有序的?
-
方法一:将topic强制采用一个分区,产生的消息自然是有顺序的
-
方法二:局部有序方式,路由将msgID计算Hash后%partition取余,消费端单线程消费
如何处理消息堆积?
-
方法一:消费者扩容
-
方法二:消息迁移Queue扩容,新建临时Topic,消费消息转发到这个临时Topic,用扩容的消费者消费临时Topic中的消息
-
方法三:优化代码,解决消费端代码消费能力不足问题
事务消息怎么实现?
如何实现MQ框架的高吞吐?
- 1、批量消费,批量处理
- 2、利用零拷贝机制,减少消息拷贝
- 3、磁盘顺序写入和读取
- 4、写消息时采取操作系统的异步刷写模式
- 5、消息分区,每个分区并发消费
- 6、消息压缩设计,节省带宽和存储空间按