9、Broker asyncSendMessage处理消息以及自动创建Topic

asyncSendMessage异步处理单条消息(在执行器线程池执行)

       调用preSend方法创建响应的命令对象,包括自动创建topic的逻辑,随后创建响应头对象。

              尝试自动创建topic:

                     校验如果当前broker没有写的权限,那么broker会返回一个NO_PERMISSION异常,sending message is forbidden,禁止向该broker发送消息。

                     校验topic不能为空,必须属于合法字符regex: ^[%|a-zA-Z0-9_-]+$,且长度不超过127个字符。

                     校验如果当前topic是不为允许使用的系统topic,那么抛出异常,默认不能为SCHEDULE_TOPIC_XXXX。

                     随后从broker的topicConfigTable缓存中根据topicName获取TopicConfig。

                     如果不存在该topic信息,比如第一次发送消息,那么首先调用createTopicInSendMessageMethod方法尝试创建普通topic,如果失败了,则判断是否是重试topic,即topic名是否以%RETRY%开头,如果是的话则尝试创建重试topic,如果还是创建失败,则返回TOPIC_NOT_EXIST异常信息。

                     如果找到或者创建了topic,则校验queutId 不能大于等于该broker的读或写的最大queueId。

              自动创建topic的弊端:

                     之前将Producer发送消息源码的时候,我们的客户端,在发送消息的之前,会先选择一个topic所在的broker地址,如果topic不存在,那么选择默认topic的路由信息中的一个broker进行发送。

                     当发送到broker之后,会发现没有指定的topic并且如果broker的autoCreateTopicEnable为true,那么将会走刚才的createTopicInSendMessageMethod源码,自动创建topic的方法的最后会马上调用registerBrokerAll方法向nameServer注册当前broker的新配置路由信息。

                     生产者客户端会定时每30s从nameServer更新路由数据,如果此时有其他的producer的存在,并且刚好从nameServer获取到了这个新的topic的路由信息,假设其他producer也需要向该topic发送信息,由于发现topic路由信息已存在,并且只存在于刚才那一个broker中,此时这些producer都会将该topic的消息发送到这一个broker中来。

                     这样,接下来所有的Producer都只会向这一个Broker发送消息,其他Broker也就不会再有机会创建新Topic。我们本想要该Topic在每个broker上都被自动创建,但结果仅仅是在一个broker上有该topic的信息,这样就背离了RocketMQ集群的初衷,不能实现压力的分摊。

                     因此,RocketMQ官方建议生产环境下将broker的autoCreateTopicEnable设置为false,即关闭自动创建topic,全部改为手动在每个broker上创建,这样安全又保险。

       随后创建MessageExtBrokerInner对象,从请求中获取消息的属性并设置到对象属性中,例如消息体,topic等等。

       判断如果是重试或者死信消息,则调用handleRetryAndDLQ方法处理重试和死信队列消息,如果已重试次数大于最大重试次数,那么替换topic为死信队列topic,消息会被发送至死信队列。

       判断如果是事务准备消息,并且不会拒绝处理事务消息,则调用asyncPrepareMessage方法以异步的方式处理、存储事务准备消息;

       否则表示普通消息,调用asyncPutMessage方法处理、存储普通消息。asyncPutMessage以异步方式将消息存储到存储器中,处理器可以处理下一个请求而不是等待结果,当结果完成时,以异步方式通知客户端。

       最后调用handlePutMessageResultFuture方法处理消息存储的处理结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值