netty基本原理
netty采用io复用 + 线程池 + 主从模式 + reactor模式 实现高性能
reactor的核心组成:1、reactor 监听多个client 事件 负责事件分发;2、handler处理 i/o 事件中要完成的实际任务;
单reactor 多线程 模型:
主从reactor多线程模型
netty框架和流程 模型
netty中常用的类
ChannelHandlerContext
ChannelOption
Unpooled类
netty心跳检测(客户端、服务端)功能 代码示例
netty通过websocket 编程实现服务器和客户端长连接(代码示例)
netty的编解码器和handler的调用机制
netty的handler中加入线程池和context中添加线程池的源码分析
netty的处理器(handler):
日志处理器:LogginHandler
心跳处理器:IdleStateHandler
http编码和解码器:HttpServerCodec
http请求响应聚合:HttpObjectAggregator 说明:http数据在传输过程中是分段,HttpObjectAggregator就是在传输过程中可以将多少个段聚合;这就是为什么 当浏览器发送大量数据时,就会发送多少次请求
http协议 升级 ws协议:WebSocketServerProtocolHandler 说明:对应 websocket 它的数据是以帧的形式传递 浏览器 请求时:ws://localhost:10001/first_socket_for_web,WebSocketServerProtocolHandler的核心功能是将http协议提升为ws协议,保持长链接
ByteToMessageDecoder:解码器
ReplayingDecoder:优雅解码器
netty中入站和出站的理解:
netty中 client端 和 server端 都可以理解是 站,socketChannel和serverSocketChannel理解为通道,从client端 -》channel和从server端-〉channel的动作称为出站,从channel-》client端和从channel-〉server端的动作称为入站;
tcp粘包和拆包案例与解决方案:
使用自定义协议+编解码器来解决;关键就是解决 服务器端每次读取数据长度的问题,这个问题解决就不会出现服务器多读或者少读数据的问题,从而避免粘包、拆包; 在传输数据和编解码过程中先发送数量,然后在发送数据,这样在接受数据的时候可以先获取int 得到数据数量,然后按照数量读取;
netty接受请求过程源码分析:
netty中Pipeline、handler、handlerContext三者关系
netty中常用的channel:
DatagramChannel用于udp数据的读写; socketChannel和serverSocketChannel用于Tcp的数据读写; FileChannel :read() write() transferFrom() transferTo()
2. NIO中三大组件关系
nio三大组件:buffer、channel、selector
常用的channel
FileChannel、 ServerSocketChannel、SocketChannel;
selector选择器
可以实现:用一个线程处理多个客户端的连接
NioEventLoop 底层就是 Selector
核心方法:select() select(timeout) selectedKeys() clear() keys() selectedKeys 和 keys两个方法的区别?
selectorkey 中四种状态 都是哪四种?connect accept read write
与netty有什么关系
Netty的IO线程 NioEventLoop 聚合了 Selector(选择器,也叫多路复用器),可以同时并发处理成百上千个客户端连接。
当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。
线程通常将非阻塞IO的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。
由于读写操作都是非阻塞的,这就可以充分提升 IO 线程的运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
一个I/O线程可以并发处理N个客户端连接和读写操作,这从根本上解决了传统同步阻塞I/O一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升
Selector、selectionKey、ServerSocketChannel和SocketChannel关系梳理图。
当客户端连接时,会通过ServerSocketChannel得到SocketChannel
将socketChannel注册到Selector上,regist(Slector sel,int ops),一个selector上可以注册多个SocketChannel。
注册后返回一个SelectionKey,回纥该Selector关联(集合)
Selector进行监听select方法,返回有事件发生通道的个数
进一步得到各个 SelectionKey (有事件发生)
再通过SelectionKey反向获取 SocketChannel,方法 channel()
可以通过 得到的 channel , 完成业务处理