扫一扫
关注公众号
一、经典的三种I/O模式
三种模式包括阻塞BIO(类似排队打饭)、非阻塞NIO(点菜)、异步AIO(包厢)。
注:要明确阻塞与非阻塞、同步与异步的区别。
延展:为什么删掉已经做好的AIO支持?什么是水平触发和边缘触发?NIO一定优于BIO嘛?
二、Netty是怎么切换IO模式的
延展:服务端切换模式后,为什么客户端不需要进行切换?
三、Netty如何支持三种Reactor
Reactor是一种开发模式,模式的核心流程是注册感兴趣的事件-》扫描是否有感兴趣的事件发生-》事件发生后做出相应的处理。
三种Reactor版本包括Reactor单线程模式、非主从Reactory多线程模式、主从Reactor多线程模式。有点类似“一个包揽所有”、“多招几个伙计”、“进一步分工”的工作模式。
源码分析:SelectorProvider
三、Netty是如何处理TCP粘包、半包的
一个发送可能可能被多次接收,多个发送可能被一次接收,而且,一个发送可能占用多个传输包,多个发送可能仅用一个传输包。背后原因是SOCK缓存区大小限制、接收方数据处理能力限制、协议MTU大小限制。
粘包、半包处理方式也就是如何寻找消息边界方式,包括改用短连接、固定长度、分割符、内容中保存长度信息。
Netty对三种常用封桢支持有FixedLengthFrameDecoder、DelimiterBasedFrameDecoder、LengthFieldBasedFrameDecoder。
注:UDP没有粘包和半包问题
源码分析:ByteToMessageDecoder#channelRead
四、常用的”二次”编解码
一次解码的结果是字节,需要转化成项目中能用的对象。
源码分析:MessageToMessageDecoder
五、keepalive与idle监测
不需要keepalive的场景:连接已坏,但是还浪费资源维持,下次直接用会直接报错。
需要keepalive的场景:对端异常”崩溃”、对端在但是处理不过来、对端在但是不可达。
设计keepalive需要考虑哪些?问题出现概率小,没有必要频繁探测。判断需”谨慎”(比如连续多少次),不能武断。
idle监测是为了减少keepalive次数的,也就是无数据传输超过一定时间后,没有读写意图,就判断为idle,然后发keepalive消息。而不是无数据传输就发keepalive消息。
注:这里说的keepalive和HTTP应用层的Connection:keep-alive长链接是不一样的。
六、Netty的那些”锁”事
(1)、在意锁的对象和范围,减少粒度。
(2)、注意锁的对象本身大小,减少空间占用。比如ChannelOutBoundBuffer中使用两个对象代替AtomicLong对象。
(3)、注意锁的速度,提高并发性。比如PlatformDependent中的代码,及时衡量和使用JDK最新的代码。
(4)、不同场景选择不同的并发包。
(5)、衡量好锁的价值,能不用则不用。
Netty使用一个队列和多个线程模式,保证了局部串行、整体并行。
七、Netty如何玩转内存使用
源码分析:DefaultChannelConfig、Recycler、PooledDirectByteBuf、PooledByteBuf、PooledByteBufAllocator