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 接这篇 在上文中,主要实现了可靠模式的 ...
随机推荐
- synchronized 关键字的用法?
synchronized 关键字可以将对象或者方法标记为同步,以实现对对象和方法的互 斥访问,可以用 synchronized(对象) { - }定义同步代码块,或者在声明方法时 将 synchron ...
- Markdown入门操作
Markdown基本操作 一. 字体 1. 标题 (1). 一级标题 "# + 标题名" (2). 其余类推 (最多支持6级标题) 加粗 " ** + 内容 + ** & ...
- js技术之获取字符串中某个字符的位置(lastIndexOf()方法 和 indexOf() 方法)
一.lastIndexOf()方法 1.作用: 方法可返回 一个指定的字符串值 在字符串中最后出现的位置.从左往右查. 2.返回: 一个正整数.或者 -1. 3.语法: stringObject.la ...
- 在IE中设置在序列化没有版本号就提示
- 《基于.NET Core构建微服务》系列文章(更新至第6篇,最新第7篇,已发布主页候选区)
原文:Building Microservices On .NET Core – Part 1 The Plan 时间:2019年1月14日 作者:Wojciech Suwała, Head Arch ...
- 使用Vue2+webpack+Es6快速开发一个移动端项目,封装属于自己的jsonpAPI和手势响应式组件
导语 最近看到不少使用vue制作的音乐播放器,挺好玩的,本来工作中也经常使用Vue,一起交流学习,好的话点个star哦 本项目特点如下 : 1. 原生js封装自己的跨域请求函数,支持promise调用 ...
- VueJs项目笔记
======================知识点总结=========================== 一.keep-alive(实现页面的缓存) 二. 移动端固定定位的解决方案 三. Vue表 ...
- 前端面试题整理——webpack相关考点
webpack是开发工具,面试考点重点在配置和使用,原理理解不需要太深. 一.基本配置 1.拆分配置和merge 将公共配置跟dev和prod的配置拆分,然后通过webpack-merge对配置进行整 ...
- 横竖屏切换android:screenOrientation属性的使用
在开发android的应用中,有时候需要限制横竖屏切换,只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制. android:sc ...
- vue上拉加载下拉加载
npm i vue-scroller <scroller :on-refresh="refresh" :on-infinite="infinite" :n ...