本文业务表现博文:稳定性 耗时 监控原因分析-- dubbo rpc 框架 的线程池,io 连接模型. 客户端,服务端
原因剖析: 共用连接,出现了排队现象,所以慢了.需要打印 zipkin 日志.
把时间点传到下游,遇到耗时高的才打印日志. 或者各处自己打印日志. 后续日志预处理时多行转列.
dubbo 基于 netty,minnay.
以 netty 为基准 :
*分为连接层
*处理层.
netty (nio ,nio2.0 )本身服务端的有多路复用的概念, 只是说 select 统一去轮训所有的连接.
dubbo 使用了长连接, 并且客户端使用了 长连接复用的概念. ( 一般服务端 用mysql 连接池 本身也是长连接,但是利用了连接池来复用长连接. )
当消费者的dubbo:reference中配置connections来单独增加消费者和服务提供者的TCP长连接的时候.
多个线程会同时向一个 tcp 通道发送数据, 异步等待数据回来,但是对调用者而言感觉又是同步的.
这种技术是通过异步来实现同步 (类似事件通知,nodejs) ,内部实现原理肯定需要将每个消息都标记一个消息 id(序号 seq , sequence ) , 异步返回的时候将 id 返回.
通过这个想法,去看源代码. 就找到了
HeaderExchangeChannel.request 方法里的 request 里的 mid. 和 DefaultFuture
一个类有什么作用不仅仅是看 field ,还要看 内部方法里使用的 类 ( 例如这里 Request 和 DefaultFuture )
dubbo 的实体关系很复杂(一个实体又充当了不同的角色 channel 和 client 的双重角色,继承了两个接口) :
HeaderExchangeChannel的作用(功能)就是 封装消息协议头,完成长连接复用的功能.
[ 画一副 dubbo 实体关系图, 1对多关系 , 启动关系, 执行关系 ,
http://blog.csdn.net/herriman/article/details/51525151 ,每个流程时的作用 ]
对于客户端:
connects 配置, n 个线程可以共用一个连接 长连接共用. 也可以使用多个连接,进行连接隔离.
phil注: 服务端配置大于客户端配置,服务端如果配置2,那么所有的消费者和服务提供者在使用这个 service 都会独立一个连接? 面试题.考察是否真的用过,还是只知道理念
对于服务端:
可配置 accepts (最大请求的连接数) 和 threads
本来dubbo 本身不需要线程池 [dubbo服务端基于 netty (netty 会有线程池,响应连接的请求)], 但由于客户端使用了长连接共用技术. 故 dubbo 本身需要在 netty 线程池的基础上,对 netty 线程 ----- 1对多 ---- 处理线程.
疑问?: netty 使用线程池后,如何进行粘包拆包? 理论上 handler 是 nio 触发的,netty 不需要线程池才对. 对 nio2理解不够深.
原因是nio 只是通知你有某个消息了,你自己要去取数据,然后取到数据后处理,循环一直等到没消息为止. 所以还是要有新的线程去处理每个数据,这样可以更快的处理完已通知到的消息.
while (true) {
Thread.sleep(1*1000);
in_selector.select(); // 阻塞 直到有就绪事件为止
// phil 注,后续处理事件. 还是有个线程去主动拉取事件.
}
对比 aio, aio是不需要自己去拉取的,完全是推送的模式.
更深刻的理解:
同步基于异步实现
netty 本身是否有 mid 的概念
客户端长连接复用
服务端 nio 的连接复用概念 (多路复用概念)
由Dubbo consumer connections 配置 研究的连接数据实现
长连接并发使用的概念
长连接复用概念
连接池复用概念
nio多路复用概念
利用异步实现同步[tcp有序号,rpc也有消息序号,消息id.粒度不同 https://blog.csdn.net/fei33423/article/details/79452282]