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 接这篇 在上文中,主要实现了可靠模式的 ...
随机推荐
- SpringMVC常用的注解有哪些?
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上.用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径. @RequestBody:注解实现接收http请求 ...
- TIME_WAIT 优化
·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟. 如果我们使用了nginx去作为 ...
- 数据分析之Pandas操作
Pandas pandas需要导入 import pandas as pd from pandas import Series,DataFrame import numpy as np 1 Serie ...
- 所有用CSS3写的3D特效,都离不开这些知识
起因 昨晚在做慕课网的十天精通CSS3课程,其中的综合练习是要做一个3D导航翻转的效果.非常高大上. 以往这些效果我都很不屑,觉得网上一大堆这些特效的代码,复制粘贴就好了,够快.但是现实工作中,其实自 ...
- python-输入列表,求列表元素和(eval输入应用)
在一行中输入列表,输出列表元素的和. 输入格式: 一行中输入列表. 输出格式: 在一行中输出列表元素的和. 输入样例: [3,8,-5] 输出样例: 6 代码: a = eval(input()) t ...
- 手机上无法显示Toast信息
关于手机上无法显示Toast信息, 是因为手机上的权限没有开, 在应用管理处将所有权限都打开,就可以显示了.
- 将base64转成File文件对象
function dataURLtoFile(dataurl, filename) { //将base64转换为文件 var arr = dataurl.split(','), ...
- python入门-开始
1.为啥要学Python? 各种语言的优劣势对比视频版:https://www.bilibili.com/video/BV1y3411r7pX/?spm_id_from=autoNext 各种语言的优 ...
- MFC---视图和窗口
视类窗口 视类窗口是指程序运行后,显示信息的那一部分.对应的类是CTestOneView(TestOne表示项目名称)类,CTestOneView类是派生于CView类,而CView类又派生于CWnd ...
- OllyDbg---寄存器
寄存器 寄存器的概念和作用 寄存器是CPU内部的高速存储单元,访问速度比常规内存快很多. 处理器在执行程序时,需要一个助手,当执行一条指令时,比如将两个内存单元中存放的内容相加,处理器需要先把其中一个 ...