Netty笔记(1) - Netty概述 和 框架结构
概述
- 基于NIO 的框架,目的是简化开发NIO的工作量
- 异步的 ,基于事件驱动的网络应用程序框架,用以快速开发高性能、高可靠性的网络 IO 程序
- Netty 是目前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、 通信行业等获得了广泛的应用
传统线程模型 和 Reactor模式
1. 传统 阻塞I/O 模型
写过原生java socket编程的都清楚 , client每次连接都会创建一个线程 用于维护连接,如果没有数据读取,线程也会一直保持阻塞,连接一多,及其耗费系统资源.
2.Reactor模式
又称为 反应器模式,分发者模式 通知者模式
特点:
-
Reactor 模式,通过一个或多个输入同时传递给服务处理器的模式(基于事件驱动)
-
服务器端程序处理传入的多个请求,并将它们同步分派到相应的处理线程, 因此Reactor模式也 叫Dispatcher模式(分发)
-
Reactor 模式使用IO复用监听事件, 收到事件后,分发给某个线程(进程)
如图所示,只需 ServiceHandler维护连接即可,并监听客户端发出的各种请求时间,并分类交由 对应的事件处理器处理,例如 连接事件,读请求,等等. 待处理完成后 ,并释放自身占用的线程.重复使用
Reactor 模式的三种实现:
单Reactor单线程:
实现思路:
-
服务器端用一个线程通过多路复用搞定所有的 IO 操作(包括连接,读、写等)
-
多客户端过来的连接 处理还是 业务处理都是同一个线程. 编码简单,清晰明了,但是如果客户端连接数量较多,将无法支撑( 接待员和服务员 是同一个人 )
单Reactor多线程
实现思路:
-
Reactor 对象通过select 监控客户端请求事件, 收到事件后,通过dispatch进行分发
-
如果建立连接请求, 则由Acceptor 通过accept 处理连接请求, 然后创建一个Handler对象处理完成连接后的各种事件
-
如果不是连接请求,则由reactor分发调用连接对应的handler 来处理
-
handler 只负责响应事件,不做具体的业务处理, 通过read 读取数据后,会分发给后面的worker线程池的某个线程处理业务
-
worker 线程池会分配独立线程完成真正的业务,并将结果返回给handler
-
handler收到响应后,通过send 将结果返回给client
Reator 仅仅只是接受各种事件,具体的工作由Worker线程池中Worker去处理,如果请求过多,单线程的Reator还是会出现瓶颈(一个接待员 多个服务员)
主从Reactor 多线程
-
Reactor主线程 MainReactor 对象通过select 监听连接事件, 收到事件后,通过Acceptor 处理连接事件
-
当 Acceptor 处理连接事件后,MainReactor 将连接分配给SubReactor
-
subreactor 将连接加入到连接队列进行监听,并创建handler进行各种事件处理
-
当有新事件发生时, subreactor 就会调用对应的handler处理
-
handler 通过read 读取数据,分发给后面的worker 线程处理
-
worker 线程池分配独立的worker 线程进行业务处理,并返回结果
-
handler 收到响应的结果后,再通过send 将结果返回给client
-
Reactor 主线程可以对应多个Reactor 子线程, 即MainRecator 可以关联多个SubReactor
监听请求的Reactor也变成多个,由主监听连接事件 由从监听其他事件 这样的组合也有可以有多个(多个接待员 多个服务员)
Netty模型
- Netty抽象出两组线程池 BossGroup 专门负责接收客户端的连接, WorkerGroup 专门负责网络的读写
- BossGroup 和 WorkerGroup 类型都是 NioEventLoopGroup
- NioEventLoopGroup 相当于一个事件循环组, 这个组中含有多个事件循环 ,每一个事件循环是NioEventLoop
- NioEventLoop 表示一个不断循环的执行处理任务的线程, 每个NioEventLoop 都有一个selector , 用于监听绑定在其上的socket的网络通讯
- NioEventLoopGroup 可以有多个线程, 即可以含有多个NioEventLoop
- 每个Boss NioEventLoop 循环执行的步骤有3步
- 轮询连接 事件
- 处理 连接 事件 , 与client建立连接 , 生成NioScocketChannel , 并将其注册到某个worker NIOEventLoop 上的 selector
- 处理任务队列的任务 , 即 runAllTasks
- 每个 Worker NIOEventLoop 循环执行的步骤
- 轮询read, write 事件
- 处理i/o事件, 即read , write 事件,在对应NioScocketChannel 处理
- 处理任务队列的任务 , 即 runAllTasks
- 每个Worker NIOEventLoop 处理业务时,会使用pipeline(管道), pipeline 中包含了 channel , 即通过pipeline 可以获取到对应通道, 管道中维护了很多的 处理器
Netty 将 Reactor 和 Handler 分别抽象为 BossGroup 和 WorkerGrop 其中每个Group中都维护了多个事件循环对象:NioEventLoop 每个事件循环 都保持一个for无限循环,监听其感兴趣的 事件发生 并处理 .