1. 解读 Netty 怎么切换 I/O 模式的?
1.1 切换开发模式
例如对于服务器开发:从 NIO 切换到 OIO
EchoServer类
NioEventLoop.run()
reactor模式
死循环监听, 处理事件
1.2 切换channel, 对应的是I/O模式, 原理是 泛型+反射+工厂
获得泛型的无参构造器,在创建连接的时候会反射出对象
constructor.newInstance(); 反射创建channel
1.3 为什么服务器开发并不需要切换客户端对应NioSocketChannel ?
NioServerSocketChannel.doReadMessages()
其中accept()实现, 创建出一个socketChannel
因为socketChannel是serverSocketChannel创建出来的
2. 解析 Netty 对 Reactor 模式支持的常见疑问
2.1 Netty 如何支持主从 Reactor 模式的?
AbstractBootstrap.java
channel在服务器开发中指的是serverSocketChannel
将serverSocketChannel绑定到了bossGroup
serverSocketChannel可以帮忙创建子的socketChannel
然后把子socketChannel绑定到workerGroup上
传参
然后绑定到childGroup里面去
总结-------------------
两种socketChannel绑定到两个group里面去 --> 完成对主从reactor模式的支持
2.2 为什么说 Netty 的 main reactor 大多并不能用到一个线程组,只能线程组里面的一个?
AbstractBootstrap.java
doBind()方法
因为对于服务器来说, 只绑定一个地址, 一个端口, 所以只会调用一次
2.3 Netty 给 Channel 分配 NIO event loop 的规则是什么
对于NIO EventGroup的实现是 MultithreadEventLoopGroup.java
next() 一种选择, 往下看 -->
chooser是一种选择器, 使用<策略模式>
第一种实现:
适用于所有的模式
第二种实现:
其中return中的 &, 在2的幂次方的时候, 会效率更高
2.4 通用模式的 NIO 实现多路复用器是怎么跨平台的
判断有没有java.nio.channels.spi.SelectorProvider这个参数
- 有的话反射出来返回true
- 没有的话返回false
使用ServiceLoader的方式
读取META-INF / services下面的配置 - 找到实现, 返回true
- 返回false
mac平台的默认实现, 确实是跨平台的
public NioEventLoopGroup(int nThreads, Executor executor) {
//默认selector,最终实现类似:
https://github.com/frohoff/jdk8u-jdk/blob/master/src/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java
//basic flow: 1 java.nio.channels.spi.SelectorProvider 2 META-INF/services 3 default
this(nThreads, executor, SelectorProvider.provider());
}