读书笔记《NettyRedisZookeeper高并发实战》Netty框架相关总结
Posted 在路上的德尔菲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读书笔记《NettyRedisZookeeper高并发实战》Netty框架相关总结相关的知识,希望对你有一定的参考价值。
- Netty优势:提供异步的、事件驱动的网络应用框架。作为一个异步框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便地主动获取或者通过机制获取IO结果。
-
API使用简单,开发门槛低。
-
功能强大,预置了各种编解码功能,支持多种主流协议。
-
定制能力强,可以通过ChannelHandler对通信框架进行灵活框架。
-
性能高,与其他业界主流NIO框架比,Netty综合性能最优。
-
成熟、稳定,Netty修复了所有JDK NIO中的BUG。
-
-
NIO 引入了Channel(通道)和Buffer(缓冲区) 的概念。读取和写入,只需要从通道中读取数据到缓冲区,或将数据从缓冲区写入到通道中。NIO不像OIO顺序操作,可以随意读取Buffer中任意位置的数据。
-
IO多路复用,指一个线程可以同时监视多个文件描述符(一个网络连接),一旦其中的一个或多个文件描述符可读或可写,系统内核就通知该线程。
-
nginx基于反应器模式,Redis也是基于反应器模式,Netty更是基于反应器模式。
-
反应器模式由Reactor反应器线程、Handlers处理器两大角色组成:
-
Reactor反应器线程:负责响应IO事件,并且分发到Handlers 处理器。
-
Handlers处理器的职责:非阻塞的执行业务处理逻辑。
-
-
最初的OIO编程中,用一个while循环,不断地监听端口是否有新的连接。问题在于前一个网络连接的handle(socket)没有处理完,那么后面的连接请求没法被接收,于是后面的请求通通会被阻塞住,服务器的吞吐量就太低了。
-
单线程Reactor反应器模式,Reactor反应器和Handler处理器都执行在一条线程上。当其中某个Handler阻塞时,会导致其他所有的Handler都得不到执行。
-
多线程Reactor反应器模式
-
升级Reactor反应器,引入多个Selector选择器,提升选择大量通道的能力。
-
升级Handler处理器,考虑使用线程池多线程能力。
-
将负责输入输出处理的IOHandler处理器的执行,放入独立的线程池中,这样业务线程与负责监听的IO事件查询的反应器线程相隔离,避免服务器的连接监听收到阻塞。
-
如果服务器为多核CPU,可以将反应器线程拆分为多个子反应器(SubReactor)线程;引入多个选择器,每一个SubReactor子线程负责一个选择器。充分释放系统资源的能力,也提高了反应器管理大量连接提升选择大量通道的能力。
-
-
反应器模式和生产者消费者模式对比:反应器是基于查询的,没有专门的队列去缓冲中存储IO事件,查询到IO事件之后,反应器会根据不同的IO选择键(事件)将其分发到对应的Handler处理器来处理。
-
反应器模式与观察者模式对比:一个IO事件绑定到一个Handler处理器上,每一个IO事件被查询到后,反应器会将事件分发到所绑定的Handler处理器;观察者模式中,同一时刻同一个主题可以被订阅过的多个观察者处理。
-
反应器模式优缺点
-
响应快,虽然同一反应器本身是同步的,但不会被单个连接的同步IO所阻塞。
-
编程相对简单,最大程度避免了复杂的多线程同步,也避免了多线程的各个线程之间切换的开销
-
可扩展,可以方便地通过增加反应器线程数的个数来充分利用CPU资源
-
反应器模式需要操作系统层面IO多路复用的支持,如Linux中的epoll。如果操作系统的底层不支持IO多路复用,反应器不会高效。
-
同一个Handler业务中,如果出现一个长时间的数据读写,会影响这个反应器中其他通道的IO处理。例如在大文件传输时,IO操作就会影响其他客户端的响应时间。
-
-
Netty核心组件:服务器启动器、缓冲区、反应器、Handler业务处理器、Future异步任务监听、数据传输通道。
-
Reactor反应器中IO事件的处理流程
-
通道注册。IO源于通道(Channel)。IO是和通道强相关的。一个IO事件一定属于某个通道,首先将通道注册到选择器上,IO事件会被选择器查询到。
-
查询选择。一个反应器会负责一个线程,不断轮询查询选择器中的IO事件
-
事件分发。如果查询到IO事件,则分发给IO事件有绑定的关系的Handler业务处理器
-
完成真正的IO操作和业务处理,这一步由Handler业务处理器负责。
-
-
在通道中发生了OP_READ事件后,会被EventLoop查询到,然后分发到ChannelInboundHandler通道入站处理器,调用它的入站处理方法read,即可以从通道中读取数据。
-
ChannelInboundHandler的默认实现为ChannelInboundHandlerAdapter,叫做通道入站处理适配器。ChannelOutboundHandler的默认实现为ChannelOutboundHandlerAdapter,叫做通道出站处理适配器。
-
反应器和通道是一对多的关系,一个反应器可以查询到很多个通道的IO事件。通道和Handler实例是多对多关系:一个通道的IO事件被多个Handler实例处理;一个Handler处理器实例也能绑定到很多的通道,处理多个通道的IO事件。
-
将有接收关系的NioserverSocketChannel和NioSocketChannel ,叫父子通道。其中NioServerSocketChannel 负责服务器连接监听和接收,也叫父通道,功能为接收新连接,创建子通道,然后初始化子通道,所以不需要特别的配置。对应每一个接收到的NioSocketChannel传输类通道, 叫做子通道。
-
Netty业务处理器流水线Channelpipeline 是基于责任链模式。内部是一个双向链表结构,能够支持动态地添加和删除Handler业务处理器。
-
Channel 、Handler、ChannelHandlerContext 关系:Channel 拥有一个ChannelPipeline通道流水线,每一个流水线节点为一个ChannelHandlerContext通道处理器上下文对象,每一个上下文中包裹了一个ChannelHandler通道处理器。
-
整个IO处理操作环节:从通道读数据包、数据包解码、业务处理、目标数据编码、把数据包写到通道,通道发送给对端。
-
ByteBuf缓冲区Pooling,可减少内存复制和GC,提升效率
-
复合缓冲区类型,支持零复制
-
不需要调用flip()方法取切换读、写模式
-
可扩展性好,例如StringBuffer
-
可以自定义缓冲区类型
-
以上是关于读书笔记《NettyRedisZookeeper高并发实战》Netty框架相关总结的主要内容,如果未能解决你的问题,请参考以下文章