您现在的位置是:首页 >其他 >消息中间件RabbitMQ&Kafka网站首页其他
消息中间件RabbitMQ&Kafka
简介消息中间件RabbitMQ&Kafka
RabbitMQ
保证消息不丢失
- 生产者确认机制
- RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功
- 生产者->交换机出错-- public-confirm nack
- 交换机->RabbitMQ出错–publish-return ack
- 消息持久化
- MQ默认是内存存储信息, 开启持久化功能可以保证存在MQ中的消息不丢失
- 消费者确认
- 消费者处理消息后可以向MQ发送ack回执, MQ收到回执后才会删除该信息
- 可以利用Spring的retry机制,在消费者出现异常时利用本地重试,设置重试次数,当次数达到了以后,如果消息依然失败,将消息投递到异常交换机,交由人工处理
消息的重复消费问题
- 每条消息设置一个唯一的标识id
- 检查数据库中数据是否存在,若不存在则处理消息,若存在则忽略,避免重复消费
- 幂等方案
- 分布式锁
- 数据库锁
死信交换机
- 延迟队列:
- 进入队列的消息会被延迟消费的队列
- 如超时订单, 定时发布
- 延迟队列 = 死信交换机+TimeToLive
- 实现延迟队列:
- 添加延迟队列插件
- 声明一个交换机, 添加delayed属性为true
- 发送消息时添加x-delay头, 值为超时时间
- 死信交换机
- 死信情况:
- 消费者使用basic.reject或basic.nack声明消费失败
- 消息是一个过期消息–超时无人消费
- 队列满后最初的消息可能成为死信
- 如果该队列配置了
dead-letter-exchange
属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机
(Dead Letter Exchange,简称DLX)。
- 死信情况:
消息堆积
当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。之后发送的消息就会成为死信,可能会被丢弃,这就是消息堆积问题
-
解决:
-
增加更多消费者提高消费速度
-
在消费者内开启线程池加快消息处理速度
-
扩大队列容积, 提高堆积上限
使用RabbitMQ的惰性队列,支持数百万条消息存储,直接存盘而非内存。
- 惰性队列:
- 惰性队列接收到消息后直接存入磁盘,
- 当消费者要消费信息时从磁盘读取并加载到内存
- 支持百万级别的消息存储
-
高可用机制
在生产环境下, 使用集群来提高可用性
- 普通集群/标准集群:
- 会在集群各个节点间分享数据, 包括交换机和队列元信息
- 队列所在节点宕机, 队列中的消息就会丢失
- 镜像集群: 本质是主从模式
- 信息会在各个mq的镜像节点中同步备份
- 创建队列的节点称为该队列的主节点, 所有操作由主节点完成, 同步给镜像节点
- 一个队列的主节点可能是另一个队列的镜像节点
- 主节点宕机后, 镜像节点成为新的主节点
- 仲裁队列: 主从同步基于Raft协议, 强一致
Kafka
消息不丢失
- 生产者发送消息到Brocker丢失
- 设置异步发送信息
- 消息重试
- 消息在Brocker中存储丢失
- 发送确认机制acks–生产者收到来自服务器的acks==0/1/all
- 消费者从Brocker接收消息丢失//重复消费
- 消费者组中的消费者若宕机且数据未更新就移交其他消费者,可能会重复消费或丢失数据
- 禁用自动提交偏移量, 改为手动–同步+异步组合提交
消费的顺序性
- 发送方发送顺序与接收方一致
- topic分区中消息只能由消费者组中的一个消费者处理, 因此消息有先后顺序
- 所以要想顺序处理Topic的所有消息, 那就只能将消息存储在同一个分区
高可用机制
-
集群模式
- Kafka集群由多个Brocker组成, 即Kafka的服务器端由被称为Brocker的服务进程构成
- 如果集群中某一台机器宕机,其他机器上的 Broker 也依然能够对外提供服务
-
分区备份机制
- topic分区有多个副本存储在多个brocker中, 一但leader发生故障, 会将其中一个副本升级为leader
- 提升系统的容错性, 高可用性
-
复制机制中的ISR
-
ISR(In-Sync Replicas)指与leader保持同步的follower副本。
-
当leader故障时,优先从ISR中选举新leader,因为它们数据一致性更高。
-
数据清理机制
- 基于消息保留时间的清理。超过指定时间就会触发清理
- 基于topic数据大小的清理,可配置删除最旧消息。
高性能设计
- 消息分区
- 存储不受单台服务器限制,可以处理更多数据
- 顺序读写
- 磁盘顺序读写, 提升读写效率
- 页缓存
- 把磁盘中的数据缓存到内存中, 把对磁盘的访问变为对内存的访问
- 零拷贝
- 减少上下文切换及数据拷贝
- 消费者消费数据->
- Kafka在内核空间查找是否存在数据->
- 不存在从磁盘读取数据拷贝到页缓存中, 同时Kafka将操作委托系统执行->
- 系统直接将页缓存中的数据拷贝给网卡发送至消费者
- 消息压缩
- 减少磁盘IO和网络IO
- 分批发送
- 将消息打包批量发送, 减少网络开销
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。