没想到吧!关于Dubbo的『消费端线程池模型』官网也写错了。 (3)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 没想到吧!关于Dubbo的『消费端线程池模型』官网也写错了。 (3)

另外,再说一下返回的类型,讲到后面的时候需要知道这个点。主要依据这个类里面定义的字段: org.apache.dubbo.rpc.protocol.dubbo.DubboCodec


image.png


对应的代码逻辑如下: org.apache.dubbo.rpc.protocol.dubbo.DubboCodec#encodeResponseData(org.apache.dubbo.remoting.Channel, org.apache.dubbo.common.serialize.ObjectOutput, java.lang.Object, java.lang.String)


image.png


这个方法从名称也知道,是对响应数据做解码操作的。


标号为①的地方是判断当前版本是否支持上下文信息传递。


标号为②的地方是判断是否是异常返回。


标号为③的地方表明不是异常返回,则判断返回值是否为 null。


标号为④的地方表明是正常返回,根据是否支持上下文信息传递,从而判断是只返回响应结果的还是既有响应结果,也有上下文信息的返回类型。


标号为⑤的地方表明是异常返回,根据是否支持上下文信息传递,从而判断是只返回异常结果的还是既有异常结果,也有上下文信息的返回类型。


好了,写到这里,协议就差不多说完了。其实不难发现这个协议就是一个偏理论的东西,这就是一个大家的约定。


所以我记起之前在一个分享大会上,一位嘉宾说的:


跨语言特性实际是RPC层的支持,本质是协议层面的支持。


我现在对这句话的理解更加深刻了。


跨语言,也就是服务异构的一种。


为什么我用 Java 发送 http 请求的时候可以不用关心对方使用的是什么开发语言?


因为大家都遵守了 http 协议,协议是可以跨语言的。


Dubbo 这种 rpc 调用的框架也一样。我发起远程调用之后,只要你能按照我们约定好的协议进行报文的解析,那你就能正常的处理我发过来的请求,我不管你的开发语言是什么。


image.png


反序列化操作到底在哪进行?


业务数据返回后,反序列化的操作到底是在哪个线程里面进行的?


是在 IO 线程里面直接解析,还是被派发到客户端线程池里面进行解析?


这个问题我们先试着在官网的线程模型介绍中去寻找答案。

http://dubbo.apache.org/zh-cn/docs/user/demos/thread-model.html

在线程模型的描述里面,是这样写的:


如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度


但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则IO 线程阻塞,将导致不能接收其它请求


如果用 IO 线程处理事件,又在事件处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。


因此,需要通过不同的派发策略和不同的线程池配置的组合来应对不同的场景。


本文不关心线程池配置,我们只看派发策略:


image.png


image.png


图片中的 Dispatch 就是派发策略发挥作用的地方。


所以我们能从这部分得出一个结论:在默认的情况下,客户端接收到响应后,由于 Dubbo 使用 all 的派发策略,会把响应请求派发到客户端线程池中去。


那我们可以推导:出响应的解析一定是在客户端线程池里面进行的吗?


不可以,推不出来的。


只能说响应会进入客户端线程池中去,但是这个响应可能是一个经过解析后的响应,也可能是一个没有经过解析的响应。


所以,这个响应有可能在进入线程池之前就被解析过了。被谁解析?


IO 线程。


如果 IO 线程没有解析,那就在客户端线程里面去解析。


根据上面这段话。我们能提炼出一个关键语句,或者说是需求:我们现在要实现响应报文可以在不同的地方进行解析的功能,请问你怎么做?


image.png


你用脚指头想也知道了。首先肯定是有一个 if 判断的,判断到底在哪(IO线程/客户端线程池)进行响应解析。而这个 if 判断的判断条件,按照 Dubbo 的尿性,肯定是可以配置的。


所以我们找到这个地方,问题就了然于心了。


我们去哪里找答案呢?


这个类里面,这个类是一个请求/响应解码的非常核心的类:

org.apache.dubbo.rpc.protocol.dubbo.DubboCodec



image.png这个类的主要干了两件事,一个是对响应报文进行解码,一个是对请求报文进行解码。

接下来我们怎么搞?强撸源码吗?不可能的。直接撸肯定费劲。


还是要搞个 Demo 跑起来,然后 Debug。


我这里的 Demo 非常简单,服务端接口实现类如下:


image.png

目录
相关文章
|
2月前
|
编解码 网络协议 API
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
|
1月前
|
消息中间件 存储 NoSQL
剖析 Redis List 消息队列的三种消费线程模型
Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表。 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 。这篇文章,我们聊聊如何使用 List 命令实现消息队列的功能以及剖析消费者线程模型 。
84 20
剖析 Redis List 消息队列的三种消费线程模型
|
18天前
|
NoSQL Redis 数据库
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
本文解释了Redis为什么采用单线程模型,以及为什么Redis单线程模型的效率和速度依然可以非常高,主要原因包括Redis操作主要访问内存、核心操作简单、单线程避免了线程竞争开销,以及使用了IO多路复用机制epoll。
35 0
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
|
5月前
|
存储 安全 Java
Qt线程池+生产者消费者模型
Qt线程池+生产者消费者模型
217 5
|
6天前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
17天前
|
消息中间件 NoSQL 关系型数据库
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
18 0
|
3月前
|
缓存 编译器 Go
开发与运维线程问题之Go语言的goroutine基于线程模型实现如何解决
开发与运维线程问题之Go语言的goroutine基于线程模型实现如何解决
53 3
|
3月前
|
算法 调度 人工智能
人工智能线程问题之无锁化编程如何解决
人工智能线程问题之无锁化编程如何解决
46 2
|
2月前
|
存储 Kubernetes NoSQL
Tair的发展问题之Tair在适配不同的存储介质时对于线程模型该如何选择
Tair的发展问题之Tair在适配不同的存储介质时对于线程模型该如何选择
|
3月前
|
Java Linux
Java演进问题之1:1线程模型对于I/O密集型任务如何解决
Java演进问题之1:1线程模型对于I/O密集型任务如何解决