钩子的注册:

DefaultMQProducerImpl#registerSendMessageHook注册钩子处理类,可注册多个。

public SendResult sendMessage(
final String addr,
final String brokerName,
final Message msg,
final SendMessageRequestHeader requestHeader,
final long timeoutMillis,
final CommunicationMode communicationMode,
final SendCallback sendCallback,
final TopicPublishInfo topicPublishInfo,
final MQClientInstance instance,
final int retryTimesWhenSendFailed,
final SendMessageContext context,
final DefaultMQProducerImpl producer
) throws RemotingException, MQBrokerException, InterruptedException {
long beginStartTime = System.currentTimeMillis();
RemotingCommand request = null;
String msgType = msg.getProperty(MessageConst.PROPERTY_MESSAGE_TYPE);
boolean isReply = msgType != null && msgType.equals(MixAll.REPLY_MESSAGE_FLAG);
if (isReply) {
if (sendSmartMsg) {
SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader);
request = RemotingCommand.createRequestCommand(RequestCode.SEND_REPLY_MESSAGE_V2, requestHeaderV2);
} else {
request = RemotingCommand.createRequestCommand(RequestCode.SEND_REPLY_MESSAGE, requestHeader);
}
} else {
if (sendSmartMsg || msg instanceof MessageBatch) {
SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader);
request = RemotingCommand.createRequestCommand(msg instanceof MessageBatch ? RequestCode.SEND_BATCH_MESSAGE : RequestCode.SEND_MESSAGE_V2, requestHeaderV2);
} else {
request = RemotingCommand.createRequestCommand(RequestCode.SEND_MESSAGE, requestHeader);
}
}
request.setBody(msg.getBody()); switch (communicationMode) {
case ONEWAY:
this.remotingClient.invokeOneway(addr, request, timeoutMillis);
return null;
case ASYNC:
final AtomicInteger times = new AtomicInteger();
long costTimeAsync = System.currentTimeMillis() - beginStartTime;
if (timeoutMillis < costTimeAsync) {
throw new RemotingTooMuchRequestException("sendMessage call timeout");
}
this.sendMessageAsync(addr, brokerName, msg, timeoutMillis - costTimeAsync, request, sendCallback, topicPublishInfo, instance,
retryTimesWhenSendFailed, times, context, producer);
return null;
case SYNC:
long costTimeSync = System.currentTimeMillis() - beginStartTime;
if (timeoutMillis < costTimeSync) {
throw new RemotingTooMuchRequestException("sendMessage call timeout");
}
return this.sendMessageSync(addr, brokerName, msg, timeoutMillis - costTimeSync, request);
default:
assert false;
break;
} return null;
}

根据消息发送方式,同步,异步,单向方式进行网络传输:

发消息请求命令是RequestCode.SEND_MESSAGE,该命令的处理类:SendMessageProcessor#sendMessage

看下handlePutMessageResult:

以上几种情况都被认为是发送成功返回,这几种都是能被感知的,至于后面几种情况做什么处理交给业务方了,而下面几种会被认为失败在客户端重试:

【mq读书笔记】mq消息发送的更多相关文章

  1. 【mq读书笔记】消息确认(失败消息,定时队列重新消费)

    接上文的集群模式,监听器返回RECONSUME_LATER,需要将将这些消息发送给Broker延迟消息.如果发送ack消息失败,将延迟5s后提交线程池进行消费. 入口:ConsumeMessageCo ...

  2. 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)

    在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...

  3. 【mq读书笔记】消息队列负载与重新分配(分配 新队列pullRequest入队)

    回顾PullMessageService#run: 如果队列总没有PullRequest对象,线程将阻塞. 围绕PullRequest有2个问题: 1.PullRequest对象在什么时候创建并加入p ...

  4. 【mq读书笔记】消息消费队列和索引文件的更新

    ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...

  5. 【mq读书笔记】消息拉取

    疑问:PullRequest何时添加? PullMessageService提供延迟添加与立即添加2种方式 疑问:PullRequest是在什么时候创建的呢? 1.上上图中 PullRequest p ...

  6. 【mq读书笔记】消息拉取长轮训机制(Broker端)

    RocketMQ并没有真正实现推模式,而是消费者主动想消息服务器拉取消息,推模式是循环向消息服务端发送消息拉取请求. 如果消息消费者向RocketMQ发送消息拉取时,消息未到达消费队列: 如果不启用长 ...

  7. 【mq读书笔记】消息过滤机制

    mq支持表达式过滤和类过滤两种模式,其中表达式又分为TAG和SQL92.类过滤模式允许提交一个过滤类到FilterServer,消息消费者从FilterServer拉取消息,消息经过FilterSer ...

  8. 【mq读书笔记】消息到达唤醒挂起线程检查新消息

    DefaultMessageStore#start 当新消息到达CommitLog是,ReputMessageService线程负责将消息转发给ConsumeQueue,IndexFile,如果Bro ...

  9. 【mq读书笔记】mq事务消息

    关于mq食物以什么样的方式解决了什么样的问题可以参考这里: https://www.jianshu.com/p/cc5c10221aa1 上文中示例基于mq版本较低较新的版本中TransactionL ...

随机推荐

  1. Charles使用part5——模拟慢网络

    一.配置参数解析: bandwidth -- 带宽,即上行.下行数据传输速度utilisation -- 带宽可用率,大部分modern是100%round-trip latency -- 第一个请求 ...

  2. STM32CubeIDE下载安装-GPIO基本配置操作-Debug调试(基于CMSIS DAP Debug)

    1.在ST官网下载STM32CubeIDE而不是STM32CubeMX,并且STM32CubeIDE是免费的.(STM32CubeIDE不支持中文路径,不然编译会出错) 2.如果你用的是keil开发环 ...

  3. Java每日一考202011.4

    1.JDK,JRE,JVM三者之间的关系 JDK包含JRE,JRE包含JVM JDK=JRE+JAVA的开发工具 JRE=JVM+JAVA核心类库 2.为什么要配置环境变量? 希望在任何路径下都能执行 ...

  4. ()C++中的赋值运算符重载函数(operator=)

    本文主要介绍C++中的重载操作符(operator)的相关知识. 概述 1.1 what operator 是C++的一个关键字,它和运算符(如=)一起使用,表示一个运算符重载函数,在理解时可将ope ...

  5. leetcode24:word-ladder-ii

    题目描述 给定两个单词(初始单词和目标单词)和一个单词字典,请找出所有的从初始单词到目标单词的最短转换序列: 每一次转换只能改变一个单词 每一个中间词都必须存在单词字典当中 例如: 给定的初始单词st ...

  6. 09-jQuery案例:爱好选择器

    爱好选择器HTML 1 <!DOCTYPE html> 2 <head> 3 <meta charset="UTF-8"> 4 <titl ...

  7. Hopfield Network 霍普菲尔德网络入门

    简介 Hopfield Network (霍普菲尔德网络),是 Hopfield 在1982年提出的一种基于能量的模型,发表的文章是 Neural networks and physical syst ...

  8. python_登陆验证文件上传下载_socket

    client.py import os import sys import json import struct import socket # 下载--接收文件 def download(sk): ...

  9. CSP-S 2020 Travels

    CSP-S 2020 Travels DAY 0 I hit the board in the morning before departure The rest of the time is dec ...

  10. linux中?*tee|\各类引号和-n-e\t\n

    1.通配符:?和*  ?   --匹配任意字符单次. *    --匹配任意字符任意次. [root@localhost test]# rm -fr *     2.管道符: |  将前面命令的结果传 ...