原理
队列读写分离
在设置主题的时候会设置读写队列数量
写队列把消息写入文件
读队列维护offset也就是consumer读取
如果不对应就会造成读不到的问题,所以一般要求的是一致的
只有缩容的时候才会先下写队列,此时就不一致
消息持久化
文件目录
abort
判断服务是否正常关闭
如果服务不正常关闭,就需要补救一些
checkpoint
存盘点
config
存放配置内容
lock
设置占用服务
commitlog
consumerqueue
index
存储消息
存储消息
commitlog
所有消息存储
按照1G分割每个文件
文件名存第一个消息的便宜量
comsumerqueue
按照topic维护
存储消费者需要消费消息的索引
内容: 索引 + size+Message Tag HashCode
内容其实就是一串数字
索引MQ就预先建了20位的数组存储
一个文件存30w个也就是6M
index
维护时间戳和消息索引
过期文件删除
根据配置可以配置一个文件的有效时间和删除时间
比如判断当前文件不是最新的之后
且在48小时内没有新的消息写入
或者是磁盘已经使用了配置比例之上了,就直接把触发删除的文件删除掉
这样会造成消息丢失,所以一般要把MQ作为数据库来用
高效文件写
零拷贝
操作系统提供的功能,一般的处理是把文件读到内存处理
零拷贝是直接操作内存中文件的地址,从而直接操作磁盘
顺序写
直接申请固定大小的磁盘空间,之后按顺序写入
刷盘
同步刷盘:内容刷入磁盘才会返回消息成功,性能差、安全性高
异步刷盘:内容由定时任务异步刷入磁盘,性能高、安全性差
消息的主从复制
集群模式:1主多从
主从之间复制:
同步复制 : 主节点同步所有从节点才会返回成功
异步复制 : 主节点写入成功就返回成功,后续异步定时同步给从节点
负载均衡
Producter
默认消息会仑村存入Topic下的MessageQueue
自然会论在不同的broker中
Consumer
集群模式
常用策略:
平均分配
轮询分配
配置指定
同机房分配
一致性哈希分配
广播模式
客户端自己维护偏移量
消息发送所有consumer
消息重试
返回
//方式1:返回 Action.ReconsumeLater,消息将重试
return Action.ReconsumeLater;
//方式2:返回 null,消息将重试
return null;
//方式3:直接抛出异常,消息将重试
throw new RuntimeException(“Consumer Message exceotion”);
处理逻辑
失败重试有的时候需要分配给其他consumer是对负载均衡的破环
所以需要重试的消息被挪到指定的队列中 “%RETRY” + ConsumerGroup
间隔时间一次递增的重试16次(间隔时间同延时队列配置的16个)
次数
随机消费:16次
顺序消费:无限次 因为一个消息不成功影响后边所有消息消费
死信队列
消息消费失败,如:重试到指定次数就放进死信队列
且队列默认不可读写,必须手动改为可读,引导进行手动介入处理
消息幂等
只保证至少消费一次
需要根据业务自己编写幂等方案