dubbo发送过程编码失败,会唤醒发送线程吗?
dubbo发送过程编码失败,会唤醒发送(客户端业务)线程吗?如何实现的?
在上篇文章 dubbo坑- No provider available for the service xxx 中,如果dubbo请求阶段,编码异常,而业务线程依然在等待响应,dubbo如何处理的?总不能等待超时,响应个超时异常吧,这不合理,接下来看dubbo编码异常,如何处理的
回顾下之前自己分析的dubbo transport层记录,详细记录了dubbo调用链路(包括netty channelhandler chain,dubbo channelhandler chain)的执行,在简单回顾下:
客户端发送:此时是在业务线程执行,客户端业务线程依次执行 InvokerInvocationHandler入口 -> RegistryDirectory获取服务集合 -> tagRouter过滤 -> 负载均衡选取一个Invoker -> dubbo consumer filter chain -> DubboInvoker执行调用invoke -> Exchange层封装请求模型Request且创建DefaultFuture并阻塞等待 -> 网络客户端NettyClient发送消息 -> dubbo Channel即NettyChannel发送 -> 调用netty channle发送 io.netty.channel.Channel.writeAndFlush(message),接着触发执行netty pipeline的outbound事件,执行顺序TailContext->NettyClientHandler->InternalEncoder->InternalDecoder->HeadContext,其中在TailContext内由业务线程切换到reactor IO线程,接着InternalEncoder进行编码,最终由HeadContext把数据发送给服务方;
客户端接收服务端响应:reactor IO线程监听到selector有read事件,执行processSelectedKeys(),触发执行netty pipeline的inbound事件,执行顺序【HeadContext->InternalDecoder->InternalEncoder->NettyClientHandler->TailContext】,由InternalDecoder解码,接着在NettyClientHandler#channelRead执行,NettyClientHandler持有dubbo channelhandler chain,因此链式执行dubbo channelhandler chain,即NettyClient->MultiMessageHandler->HeartbeatHandler->AllChannelHandler->DecodeHandler->HeaderExchangeHandler->DubboProtocol$1,这里重要的是在AllChannelHandler内由IO线程切换到业务线程(封装响应Response为ChannelEventRunnable,提交到dubbo业务线程池),接着在业务线程上HeaderExchangeHandler判断mesage是Response,处理响应,唤醒DefaultFuture的阻塞等待。
接着客户端业务线程被唤醒,根据Response内容处理,获取返回的数据结果/异常。
以上就是dubbo整个发送-响应的整个流程,重点是netty pipeline和dubbo channelhandler chain,都是责任链模式增加功能。
接着分析我们这个问题,从上面回顾的流程可知,未实现序列化,那么异常肯定发生在dubbo编码阶段,即InternalEncoder抛出异常,异常是java.lang.RuntimeException,异常信息Serialized class com.zzz.ioc.codec.util.KeyValuePair must implement java.io.Serializable Java field: private com.zzz.ioc.codec.util.KeyValuePair com.zzz.ioc.protocol.t808.T0900.message
,异常封装在netty DefaultChannelPromise,因此在NettyClientHandler获取InternalEncoder.write结果(此过程在IO线程执行),判断是否有无异常,代码如下
消息发送有异常,则mock response返回,接着执行NettyClientHandler持有的dubbo channelhandler chain[NettyClient->MultiMessageHandler->HeartbeatHandler->AllChannelHandler->DecodeHandler->HeaderExchangeHandler->DubboProtocol$1],AllChannelHandler执行,IO线程切换到业务线程(dubbo客户端线程池,线程名称DubboClientHandler-开头),接着业务线程上执行HeaderExchangeHandler,处理response,唤醒发送等待线程。此过程为了避免write操作失败,mock Request,然后和正常接收响应基本一样的处理方式(不同之处是不经过selector的processSelectedKeys())唤醒发送线程。通信框架出现这个问题也不容易,但是dubbo设计的非常巧妙。
小结:
回答前面提问
1.dubbo发送过程编码失败,会唤醒发送线程吗?
会唤醒发送线程,否则发送线程就是timeout异常,实际并没有。
如何实现的?
发送异常,比如编码异常,NettyClientHandler 进行mock response,接着和正常处理响应基本相同方式,触发NettyClientHandler 持有的dubbo channelhandler chain,由AllChannelHandler封装响应Response为ChannelEventRunnable,提交到dubbo业务线程池(cache线程池,线程名DubboClientHandler-
开头),线程由IO线程切换到dubbo业务线程执行Exchange,即HeaderExchangeHandler处理response,继而唤醒发送线程,最后发送(客户端业务)线程处理响应业务逻辑。
dubbo发送过程编码失败,会唤醒发送线程吗?的更多相关文章
- 关于XE10下Indy发送字符串编码的问题
在与硬件对接的过程中,之前用D7环境下的UDPServer.Post发送的指令,硬件可正常识别并正常显示, 后来使用到XE10,重新编译之前的源码,发现所有汉字乱码显示了: 后通过对接收数据发现,实际 ...
- RocketMQ源码 — 三、 Producer消息发送过程
Producer 消息发送 producer start producer启动过程如下图 public void start(final boolean startFactory) throws MQ ...
- [转]Linux网络 - 数据包的发送过程
转, 原文:https://segmentfault.com/a/1190000008926093 -------------------------------------------------- ...
- 鸿蒙内核源码分析(信号生产篇) | 信号安装和发送过程是怎样的? | 百篇博客分析OpenHarmony源码 | v48.03
百篇博客系列篇.本篇为: v48.xx 鸿蒙内核源码分析(信号生产篇) | 年过半百,依然活力十足 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管 ...
- jenkins将构建成功或失败的信息发送给指定URL(eg: pomelo采用jenkins持续集成)
先提供一个思路供大家参考,想将构建成功或者失败的信息发送给指定URL的话,可以这样:1.A构建后触发另一个构建B,构建B执行某个插件2.插件的功能: (1)利用jenkins API获取构建A最 ...
- Telnet 模拟邮件发送过程
Telnet 模拟邮件发送过程 windows要提前开启Telnet客户端的功能,再按照下面步骤完成邮件发送: 1.通过 cmd 进入命令窗口 2.连接要发送邮件的服务器:telnet smtp.al ...
- Android4.4 Telephony流程分析——彩信(MMS)发送过程
本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. 彩信收发依靠WAP网络,在Android4.4中的实现基于Http协议的应用.下图为几个彩信传 ...
- 4、下行短信发送WebService、下行短信发送服务 -功能详细设计 --短信平台
3. 下行短信发送WebService 开发一个WebService,供第三方系统调用,用于发送短信.WebService接收数据后,将信息存储入数据库的短信发送数据表中. WebService参数 ...
- rabbitmq 不发送ack消息如何处理:rabbitmq可靠发送的自动重试机制
转载地址:http://www.jianshu.com/p/6579e48d18ae http://www.jianshu.com/p/4112d78a8753 接这篇 在上文中,主要实现了可靠模式的 ...
随机推荐
- switch 是否能作用在 byte 上,是否能作用在 long 上, 是否能作用在 String 上?
在 Java 5 以前,switch(expr)中,expr 只能是 byte.short.char.int.从 Java 5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 ...
- windows服务器下frp实现内网穿透
一.操作步骤 1.服务器:首先在服务器上解压到相应目录并配置frps.ini文件如下: 2.服务器:按下windows+R输入cmd进入命令窗口,进入到安装目录下运行frps.exe -c frps. ...
- Elasticsearch 是如何实现 Master 选举的?
1.Elasticsearch 的选主是 ZenDiscovery 模块负责的,主要包含 Ping(节点之 间通过这个 RPC 来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪 些节点 ...
- 您对 Distributed Transaction 有何了解?
分布式事务是指单个事件导致两个或多个不能以原子方式提交的单独数据源的突 变的任何情况.在微服务的世界中,它变得更加复杂,因为每个服务都是一个工 作单元,并且大多数时候多个服务必须协同工作才能使业务成功 ...
- 哪些是重要的 bean 生命周期方法?你能重载它们吗?
有两个重要的 bean 生命周期方法,第一个是 setup , 它是在容器加载 bean 的时候被调用.第二个方法是 teardown 它是在容器卸载类的时候被调用. The bean 标签有两个重要 ...
- 学习heartbeat-03t实现web服务的高可用案例及维护要点
8.Heartbeat实现web服务的高可用案例 8.1部署准备 通过web服务高可用案例来熟悉heatbeat软件的使用,用上面的两台服务器机器名分别为heartbeat-1-130和heartbe ...
- Visual Studio App Center 中的 Bug 跟踪服务
我在之前的一篇文章 <使用 Visual Studio App Center 持续监视应用使用情况和问题> 中介绍了 App Center 的基本功能及使用入门,其中 诊断 可以自动手机用 ...
- 在 VC 下清空键盘缓冲区的方法
控制台窗口是有输入缓冲区的,当你按键后程序没有来得及处理,系统会将按键缓存,等到程序获取按键的时候,系统会把缓冲区里面之前的按键返回. // 调用控制台 API,清空之前缓冲区内的所有按键. Flus ...
- 带你玩转prefetch, preload, dns-prefetch,defer和async
现代浏览器性能优化-JS篇 众所周知,JS的加载和执行会阻塞浏览器渲染,所以目前业界普遍推荐把script放到</body>之前,以解决js执行时找不到dom等问题.但随着现代浏览器的普及 ...
- js压缩图片到2m以下
用的canvas.这个问题测试妹子反馈了好几次bug,解决了好多次,虽然用了比较僵硬的办法,但总算最终解决了. 因为php的同事说,页面上的图片要直接调用七牛的接口上传到七牛,所以后端那边不能处理,必 ...