钩子的注册:

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

  1. public SendResult sendMessage(
  2. final String addr,
  3. final String brokerName,
  4. final Message msg,
  5. final SendMessageRequestHeader requestHeader,
  6. final long timeoutMillis,
  7. final CommunicationMode communicationMode,
  8. final SendCallback sendCallback,
  9. final TopicPublishInfo topicPublishInfo,
  10. final MQClientInstance instance,
  11. final int retryTimesWhenSendFailed,
  12. final SendMessageContext context,
  13. final DefaultMQProducerImpl producer
  14. ) throws RemotingException, MQBrokerException, InterruptedException {
  15. long beginStartTime = System.currentTimeMillis();
  16. RemotingCommand request = null;
  17. String msgType = msg.getProperty(MessageConst.PROPERTY_MESSAGE_TYPE);
  18. boolean isReply = msgType != null && msgType.equals(MixAll.REPLY_MESSAGE_FLAG);
  19. if (isReply) {
  20. if (sendSmartMsg) {
  21. SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader);
  22. request = RemotingCommand.createRequestCommand(RequestCode.SEND_REPLY_MESSAGE_V2, requestHeaderV2);
  23. } else {
  24. request = RemotingCommand.createRequestCommand(RequestCode.SEND_REPLY_MESSAGE, requestHeader);
  25. }
  26. } else {
  27. if (sendSmartMsg || msg instanceof MessageBatch) {
  28. SendMessageRequestHeaderV2 requestHeaderV2 = SendMessageRequestHeaderV2.createSendMessageRequestHeaderV2(requestHeader);
  29. request = RemotingCommand.createRequestCommand(msg instanceof MessageBatch ? RequestCode.SEND_BATCH_MESSAGE : RequestCode.SEND_MESSAGE_V2, requestHeaderV2);
  30. } else {
  31. request = RemotingCommand.createRequestCommand(RequestCode.SEND_MESSAGE, requestHeader);
  32. }
  33. }
  34. request.setBody(msg.getBody());
  35.  
  36. switch (communicationMode) {
  37. case ONEWAY:
  38. this.remotingClient.invokeOneway(addr, request, timeoutMillis);
  39. return null;
  40. case ASYNC:
  41. final AtomicInteger times = new AtomicInteger();
  42. long costTimeAsync = System.currentTimeMillis() - beginStartTime;
  43. if (timeoutMillis < costTimeAsync) {
  44. throw new RemotingTooMuchRequestException("sendMessage call timeout");
  45. }
  46. this.sendMessageAsync(addr, brokerName, msg, timeoutMillis - costTimeAsync, request, sendCallback, topicPublishInfo, instance,
  47. retryTimesWhenSendFailed, times, context, producer);
  48. return null;
  49. case SYNC:
  50. long costTimeSync = System.currentTimeMillis() - beginStartTime;
  51. if (timeoutMillis < costTimeSync) {
  52. throw new RemotingTooMuchRequestException("sendMessage call timeout");
  53. }
  54. return this.sendMessageSync(addr, brokerName, msg, timeoutMillis - costTimeSync, request);
  55. default:
  56. assert false;
  57. break;
  58. }
  59.  
  60. return null;
  61. }

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

发消息请求命令是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. 4g物联网模块的原理

    4G DTU模块也可以被称之为是含有第四代移动通信技术的模块,是随着科技不断发展进步下物联网和移动互联网发展下的又一产物.而4G技术包括TD-LTE和FDD-LTE两种制式.集3G与WLAN于一体并能 ...

  2. Maven打包过程

    1.安装maven 下载地址:http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.1/binaries/apache-maven- ...

  3. Java每日一考202011.4

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

  4. c#分割

    Hashtable h = new Hashtable(); ArrayList l = new ArrayList(); string[] lines = System.IO.File.ReadAl ...

  5. 【QT】跨线程的信号槽(connect函数)

    线程的信号槽机制需要开启线程的事件循环机制,即调用QThread::exec()函数开启线程的事件循环. Qt信号-槽连接函数原型如下: bool QObject::connect ( const Q ...

  6. 16flask错误处理

    1,A secret key is required to use CSRF 使用CSRF需要一个密钥,也就是说没有设置秘钥

  7. Python之Matplot——01.堆叠柱状图的绘制

    1.Matplotlib是python的一个绘图库,可以方便的绘制各种图标,是数据可视化的利器. 2.本文我就给大家介绍一下条形图或者说柱状图的绘制 3.代码如下: <1>首先导入模块 1 ...

  8. Spider--补充--Re模块_2

    # @ Author : Collin_PXY # Python 正则表达式的应用(二) # 正则表达式之所以让人头疼,很大程度是因为表达式里有大量的符号及它们的组合,还有很多匹配模式,想要记住比较困 ...

  9. 329. Longest Increasing Path in a Matrix(核心在于缓存遍历过程中的中间结果)

    Given an integer matrix, find the length of the longest increasing path. From each cell, you can eit ...

  10. MySQL中EXPLAIN结果的参数详解

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了.如: mysql& ...