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对多关系 , 启动关系, 执行关系 ,

Dubbo源码学习之知识点分析 和 续

,每个流程时的作用 ]

 

 

对于客户端:

     connects 配置,  n 个线程可以共用一个连接 长连接共用. 也可以使用多个连接,进行连接隔离.

 

  • <dubbo:service connections=”0”>或<dubbo:reference connections=”0”>表示该服务使用JVM共享长连接。(缺省)
  • <dubbo:service connections=”1”>或<dubbo:reference connections=”1”>表示该服务使用独立长连接。
  • <dubbo:service connections=”2”>或<dubbo:reference connections=”2”>表示该服务使用独立两条长连接。可以继续配置3,4,5.

    phil注: 服务端配置大于客户端配置,服务端如果配置2,那么所有的消费者和服务提供者在使用这个 service 都会独立一个连接? 面试题.考察是否真的用过,还是只知道理念

 

对于服务端:

 

    可配置 accepts (最大请求的连接数) 和 threads

     <dubbo:protocol name="dubbo"port="8888" threads="500"accepts="200"/>

 

本来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.粒度不同 ]