RocketMQ的Request-Reply特性源码初探和实践

大概的流程参考

快速学习-RocketMQ-“Request-Reply”特性_cwl_java的博客-CSDN博客_rocketmq 请求应答

解读RocketMQ对RPC的设计实现原理_林风自在的博客-CSDN博客_rocketmq rpc

使用此特性可以达到同步调用的效果

本文主要是源码讲述,以及reqest/reply模式调优调优。分析jar的版本基于4.7.1

优劣势

优势

  1. mq达到同步调用效果
  2. 消费者可重试处理

劣势

  1. 相比rpc接口直接调用,耗时会增加
  2. 生产端重启不能接受到返回结果

总结:可以达到同步效果的作用,利用mq可以作为存储消息的队列。如果用做大流量削峰的模式不是很合适,本身功能是同步。可作为一定量的流量削峰。

源码分析

初始化MQClientInstance

 org.apache.rocketmq.client.impl.factory.MQClientInstance#MQClientInstance(org.apache.rocketmq.client.ClientConfig, int, java.lang.String, org.apache.rocketmq.remoting.RPCHook)

NettyRemotingClient是rocketmq服务端交互类

初始化MQClientAPIImpl

org.apache.rocketmq.client.impl.MQClientAPIImpl#MQClientAPIImpl

NettyRemotingClient交互时注册处理的命令有哪些的。

RequestCode.PUSH_REPLY_MESSAGE_TO_CLIENT是request/reply模式下,处理回复的命令

初始化NettyRemotingClient交互命令的线程池

org.apache.rocketmq.remoting.netty.NettyRemotingClient#NettyRemotingClient(org.apache.rocketmq.remoting.netty.NettyClientConfig, org.apache.rocketmq.remoting.ChannelEventListener)

启动上述初始化对象

org.apache.rocketmq.client.impl.factory.MQClientInstance#start

NettyRemotingClient启动过程

org.apache.rocketmq.remoting.netty.NettyRemotingClient#start

 NettyClientHandler实例化及处理过程分析

读取rocketmq交互中的命令内容

org.apache.rocketmq.remoting.netty.NettyRemotingClient.NettyClientHandler

org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#processRequestCommand

 

看到这里,了解,获取的是空的,走的就是defaultRequestProcessor,因为在注册命令的是否,线程池填写的为空。把命令处理过程中放到线程池

org.apache.rocketmq.client.impl.ClientRemotingProcessor#processRequest

 

MessageConst.PROPERTY_CORRELATION_ID放到头部中,消费者进行消费时,回复时需要把这个信息给返回过来,才能找到对应是生产者的等待线程。

实践

1 项目中用此模式,尽量让代码通用,减少后续工作量

本质上对于服务提供方来说,mq消费只是多一条调用的渠道而已。所以生产者把接口,调用方法,请求参数进行序列化,通过mq传到消费者。消费者反序列化,调用。这里可以通过反射进行调用,可以做到通用

2 超时处理

2.1 生产者等待消费者消息回复超时,会报RequestTimeoutException,针对此异常,可根据业务的异常,进行包装处理

2.2  消费者处理超时

2.2.1 消息在rocketmq积压太久,接受到消息,就已超过业务自己定义超时时间。

2.2.2 消息经过业务逻辑处理后,已超过业务自己定义超时时间。

3 发送时间,超时时间定义

发送时间:生产消息时,将发送时间的时间戳,发送过来

超时时间定义:发送时间的request就已定义,放到头部已发送过来requestMessage.getProperty(MessageConst.PROPERTY_MESSAGE_TTL);

注意:

回复的消息的一定用rocketmq的工具类方法,会组装必须的回复头部数据,具体的例子可以参考rocketmq提供的dome

MessageUtil.createReplyMessage(messageExt, replyContent);

调优

通过上述,已知道机制

同步调用请求很多,生产者接受到回复的消息也很多,如果线程池线程少肯定会造成拥堵,造成不必要的超时

1 调整生者者接受回复请求的线程池数组的线程数。

默认是cpu的数量

//#producer的client接受rockemq推送请求并发量,处理请求.request/repaly模式很重要,默认是cpu核心的数量
  producer.setClientCallbackExecutorThreads(clientCallbackExecutorThreads);

2  netty和服务端的交互的工作线程数

目前nettty工作线程数量固定4个,代码已写死,目前是调不了的。如果1的数量足够合理,这个过程是异步的,加到线程池处理,速度是很快的。调优优先机不高,要调,需要改源码

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值