消息投递:
生产者投递
1,投递默认算法轮询算法获得投递queue
2,默认投递方式的增强:轮序和投递延迟最小策略
3,顺序消息选择投递策略,根据arg(传入的object 进行对mq的queue的size进行取模达到放在同一队列的目的)
4,生产者push到broker中,而消费者会生成监听器(角色篇)
消费者拉取(见角色篇)
1,可以按照消费者消费能力拉取
2,容易因为没有消息造成空拉取
3,容易因为拉取的频率过低造成消息堆积
注意:为消费者分配队列默认也是轮询,其中包括临近机房和基于hash环的hash算法
消息重试
重试条件:
1,未返回状态
2,返回状态为unknow
3,消费端执行消息期间出现异常且未被捕获
重试策略:
1.设置最大重试次数
2.重试成功消息被标记已消费
3.如果是顺序消息会阻塞
死信消息:
1,产生原因:消息达到最大次数之后消息会变成死信
2,死信消息并非一定是没有被消费的消息,也会有消费后消费端失去连接的情况
3,死信topic的命名为:%DLQ% + Consumer组名
4,死信消息特点:1.对消费者不可见,2.有效期和正常消息一样会被存放三天
5,死信消息队列特点:组共享,第一次出现死信消息是产生队列,每个死信消息持有一个groupId
6处理方式:1.通过console控制台手动推消息进行消费,也可以查询死信消息所在原topic重新消费-->新问题:如何保证幂等?
幂等性处理:
出现原因:
重复投递:服务端(broker重启扩容缩容操作时触发的rebalance)
重复消费:消费成功之后返回服务端时无法连接服务端
重复发送:发送成功未收到服务端响应
本人提供方案:
1.通过redis生成uuid并使用bitMap保存,消息成功消费后删除redis中uuid对应的数据.每次消息消费前去验证
2.客户端生成唯一标识,消费成功之后会存入redis,同样使用bitMap 消息消费前先去查下是否已被登记
3.为了程序健壮性缓存和唯一索引结合最佳
4.rocketMQ准备了key可以用来存唯一标识