rocketmq存储消息mysql_再说rocketmq消息存储

本文详细介绍了RocketMQ在接收到消息请求后,如何通过Netty处理,并深入讲解了从消息接收、处理到存储的整个流程。重点讨论了SendMessageProcessor类在消息处理中的角色,以及消息最终如何被持久化到MappedByteBuffer并进行刷盘操作。同时,文章还提到了刷盘策略(同步和异步)以及相关组件的作用,如GroupCommitService和MapedFileQueue。
摘要由CSDN通过智能技术生成

两篇精彩的文章:

rocketmq通过netty获取到消息请求后,直接掉处理模块,比如:SendMessageProcessor

这个处理类主要负责处理客户端发送消息的请求。

这个类实现了com.alibaba.rocketmq.remoting.netty.NettyRequestProcessor接口。这个接口下一共两个方法:

RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request)

throws Exception;

boolean rejectRequest();

加粗的方法是我们接下来要讲的方法。

它同时还继承了com.alibaba.rocketmq.broker.processor.AbstractSendMessageProcessor。

我们先看一下这个过程的调用链:

feab04e0b79db820c73588161c0706cc.png

这里有一篇博客写的特别好:http://www.cnblogs.com/sunshine-2015/p/6291116.html

再次基础之上补充一点点东西。

首先进入SendMessageProcessor类的第一个方法是:

c9fa50b2dfb9747f8e1ba472314dc8e3.png

这个类什么时候被调用的呢?肯定是netty通信模块接收到消息后调用了,具体实在这里:

ea5681de4fcabe2c71b0c791d26d3db9.png

就是箭头所指的地方调用的上面那个方法。

我们看一下完整的从netty通信模块接收消息到这里的整个过程:

a24bb0465c9906ab00e7a7446232de68.png

现在就到了我们非常熟悉的Handler了。

8aa167de6b779b6b8d066103c6f5e5be.png

79a35175706f7646cc49682981d5b32a.png

这里从下往上看会更加的直观。

好了,我们接着往消息存储走。

我们进入这个方法:

dae6c37f6679b98d0c4f66456d134f87.png

private RemotingCommand sendMessage(final ChannelHandlerContext ctx, // final RemotingCommand request, // final SendMessageContext sendMessageContext, // final SendMessageRequestHeader requestHeader) throwsRemotingCommandException {final RemotingCommand response = RemotingCommand.createResponseCommand(SendMessageResponseHeader.class);final SendMessageResponseHeader responseHeader =(SendMessageResponseHeader) response.readCustomHeader();

response.setOpaque(request.getOpaque());

response.addExtField(MessageConst.PROPERTY_MSG_REGION,this.brokerController.getBrokerConfig().getRegionId());if(log.isDebugEnabled()) {

log.debug("receive SendMessage request command, " +request);

}final long startTimstamp = this.brokerController.getBrokerConfig().getStartAcceptSendRequestTimeStamp();if (this.brokerController.getMessageStore().now()

response.setCode(ResponseCode.SYSTEM_ERROR);

response.setRemark(String.format("broker unable to service, until %s", UtilAll.timeMillisToHumanString2(startTimstamp)));returnresponse;

}

response.setCode(-1);super.msgCheck(ctx, requestHeader, response);if (response.getCode() != -1) {returnresponse;

}final byte[] body =request.getBody();int queueIdInt =requestHeader.getQueueId();

TopicConfig topicConfig= this.brokerController.getTopicConfigManager().selectTopicConfig(requestHeader.getTopic());if (queueIdInt < 0) {

queueIdInt= Math.abs(this.random.nextInt() % 99999999) %topicConfig.getWriteQueueNums();

}int sysFlag =requestHeader.getSysFlag();if (TopicFilterType.MULTI_TAG ==topicConfig.getTopicFilterType()) {

sysFlag|=MessageSysFlag.MultiTagsFlag;

}

String newTopic=requestHeader.getTopic();if ((null != newTopic &&newTopic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX))) {

String groupName=newTopic.substring(MixAll.RETRY_GROUP_TOPIC_PREFIX.length());

SubscriptionGroupConfig subscriptionGroupConfig=

this.brokerController.getSubscriptionGroupManager().findSubscriptionGroupConfig(groupName);if (null ==subscriptionGroupConfig) {

response.setCode(ResponseCode.SUBSCRIPTION_GROUP_NOT_EXIST);

response.setRemark("subscription group not exist, " + groupName + " " +FAQUrl.suggestTodo(FAQUrl.SUBSCRIPTION_GROUP_NOT_EXIST));returnresponse;

}int maxReconsumeTimes =subscriptionGroupConfig.getRetryMaxTimes();if (request.getVersion() >=MQVersion.Version.V3_4_9.ordinal()) {

maxReconsumeTimes=requestHeader.getMaxReconsumeTimes();

}int reconsumeTimes =requestHeader.getReconsumeTimes();if (reconsumeTimes >=maxReconsumeTimes) {

newTopic=MixAll.getDLQTopic(groupName);

queueIdInt= Math.abs(this.random.nextInt() % 99999999) %DLQ_NUMS_PER_GROUP;

topicConfig= this.brokerController.getTopicConfigManager().createTopicInSendMessageBackMethod(newTopic, // DLQ_NUMS_PER_GROUP, // PermName.PERM_WRITE, 0);if (null ==topicConfig) {

response.setCode(ResponseCode.SYSTEM_ERROR);

response.setRemark("topic[" + newTopic + "] not exist");returnresponse;

}

}

}

MessageExtBrokerInner msgInner= newMessageExtBrokerInner();

msgInner.setTopic(newTopic);

msgInner.setBody(body);

msgInner.setFlag(requestHeader.getFlag());

MessageAccessor.setProperties(msgInner, MessageDecoder.string2messageProperties(requestHeader.getProperties()));

msgInner.setPropertiesString(requestHeader.getProperties());

msgInner.setTagsCode(MessageExtBrokerInner.tagsString2tagsCode(topicConfig.getTopicFilterType(), msgInner.getTags()));

msgInner.setQueueId(queueIdInt);

msgInner.setSysFlag(sysFlag);

msgInner.setBornTimestamp(requestHeader.getBornTimestamp());

msgInner.setBornHost(ctx.channel().remoteAddress());

msgInner.setStoreHost(this.getStoreHost());

msgInner.setReconsumeTimes(requestHeader.getReconsumeTimes()== null ? 0: requestHeader.getReconsumeTimes());if (this.brokerController.getBrokerConfig().isRejectTransactionMessage()) {

String traFlag=msgInner.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);if (traFlag != null) {

response.setCode(ResponseCode.NO_PERMISSION);

response.setRemark("the broker[" + this.brokerController.getBrokerConfig().getBrokerIP1() + "] sending transaction message is forbidden");returnresponse;

}

}

// 前面是一些系统检查和数据准备,下面进入消息存储环节。

PutMessageResult putMessageResult= this.brokerController.getMessageStore().putMessage(msgInner);

// 锚点putMessageif (putMessageResult != null) {boolean sendOK = false;switch(putMessageResult.getPutMessageStatus()) {//Success

casePUT_OK:

sendOK= true;

response.setCode(ResponseCode.SUCCESS);break;caseFLUSH_DISK_TIMEOUT:

response.setCode(ResponseCode.FLUSH_DISK_TIMEOUT);

sendOK= true;break;caseFLUSH_SLAVE_TIMEOU

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值