第4章 Netty 第一节概述
发布时间:2023年12月20日
1. 原生NIO存在的问题
- NIO的类库和API繁杂,使用麻烦。需要熟练掌握Selector, ServerSocketChannel, SocketChannel, ByteBuffer等。
- 开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等等。
2. Netty官方说明
- Netty 是由JBOSS提供的一个Java开源框架,Netty提供异步的,基于事件驱动的网络应用程序框架,用以快速开发高性能,高可靠的网络IO程序。
- Netty 可以帮助你快速、简单的开发出一个网络应用,相当于简化和流程化了 NIO 的开发过程。
- Netty 是目前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,知名的 Elasticsearch 、Dubbo 框架内部都采用了 Netty。
3. Netty的优点
- 设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池.
- 高性能、吞吐量更高:延迟更低;减少资源消耗;最小化不必要的内存复制。
4. 线程模型基本介绍
- 目前存在的线程模型:
5. Reactor模式
5.1 单Reactor单线程
前面的群聊实例就是这种方式:服务器端用一个线程通过多路复用搞定所有的 IO 操作(包括连接,读、写等),编码简单,清晰明了,但是如果客户端连接数量较多,将无法支撑,前面的 NIO 案例就属于这种模型。
方案优缺点分析:
- 优点:模型简单,没有多线程,进程通信,资源竞争问题。全部在一个线程中完成。
- 缺点:性能问题,只有一个线程,无法完全发挥多核CPU的性能
- 使用场景:客户端的数量有限,业务处理非常快速,比如 Redis在业务处理的时间复杂度 O(1) 的情况
5.2 单Reactor多线程
说明:
- Reactor对象通过select 监控客户端请求时间,收到事件后,通过dispatch进行分发。
- 如果建立连接请求,则acceptor荣国accept处理请求,然后创建handler对象处理完成连接后的各种事件
- 如果不是连接请求,则由reactor分发调用连接对应的handler处理。
- handler只负责响应事件,不做具体的业务处理,通过read读取数据后,分发给后面的worker线程池的某个线程处理任务。
- worker线程池会分配独立线程完成真正的业务,并将结果返回给handler.
- handler收到响应后,通过send将结果返回client
方案优缺点分析: - 优点:可以充分利用多核cpu的处理能力
- 缺点:多线程数据共享和访问比较复杂,reactor处理所有的事件的监听和响应,在单线程运行,在高并发场景容易出现性能瓶颈。
- 使用场景:客户端的数量有限,业务处理非常快速,比如 Redis在业务处理的时间复杂度 O(1) 的情况
5.3 主从Reactor多线程
说明:
- Reactor主线程MainReactor对象通过select监听连接事件,收到事件后,通过acceptor处理连接事件。
- 当acceptor处理连接事件后,MainReactor将连接分配给SubReactor.
- subreactor将连接加入连接队列进行监听,并创建handler进行各种事件处理
- 当有新事件发生时,subreactor调用对应的handler进行处理
- handler通过reade读取数据,分发给后面的worker线程池处理
- worker线程池分配独立的线程进行业务处理,并返回结果
- handler收到响应的结果后,再通过send将结果返回给client
- reactor主线程可以对应多个reactor子线程,即MainReactor可以关联多个subreactor
方案优缺点分析: - 优点:父线程和子线程的数据交互简单职责明确,父线程只需要接受新连接,子线程完成后续的业务处理。
- 缺点:编程难度高。
- 使用场景:这种模型在许多项目中广泛使用,包括 Nginx 主从 Reactor 多进程模型,Memcached 主从多线程,Netty 主从多线程模型的支持
6. Reactor模式小结
- 单Reactor单线程,前台接待员和服务员是同一个人
- 单Reactor多线程,1个前台接待员,多个服务员。
- 主从Reactor多线程,多个前台接待员,多个服务员。
Reactor模式优点: - 响应快,不必为单个同步时间所阻塞,虽然 Reactor 本身依然是同步的
- 可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销
- 扩展性好,可以方便的通过增加 Reactor 实例个数来充分利用 CPU 资源
- 复用性好,Reactor 模型本身与具体事件处理逻辑无关,具有很高的复用性
7. Netty模型
7.1 Netty简单版
Netty主要基于主从reactors多线程模型做了一定的改进,其中主从reactor多线程模型有多个reactor
说明:
- BossGroup线程维护selector,他只关注accept
- 当接收到accept事件后,获取到对应的socketchannel,封装成NIOsocketChannel并注册到worker线程(事件循环),并进行维护
- 当worker线程监听到selector中通道发生自己感兴趣的事件后,就进行处理(hanlder).注意handler已经加入到通道中。
7.2 Netty进阶版
7.2 Netty详细版
说明:
- Netty抽象出两组线程池BossGroup专门负责接受客户端的连接,workerGroup专门负责网络的读写
- BossGroup和workerGroup类型都是NIOEventLoopGroup
- NIOEventLoopGroup 相当于是一个事件循环组,这个组中包含多个事件循环,每一个事件循环都是NIOEventLoop.
- NIOEventLoop表示一个不断循环的执行处理任务的线程,每个NIOEventLoop都有一个selector,用户监听绑定在其上的socket网络通讯。
- NIOEventLoopGroup可以有多个线程,即可以含有多个NIOEventLoop
- 每个bossNIOEventLoop循环执行的步骤有三步
- 轮询accept事件
- 处理accept事件,与client建立连接,生成NIOsocketChannel并将其注册到某个wokerNIOEventLoop上的selector。
- 处理任务队列的任务,即runAllTasks
- 每个workerNIOEventLOOP循环执行的步骤
- 轮询read,write事件
- 处理IO事件,即read,write事件,在对应NIOSocketChannel处理
- 处理任务队列的任务,即runAllTasks
- 每个workerNIOEventLoop处理业务时,会使用pipeline(管道)pipeline中包含了channel,即通过pipeline可以获取到对应的管道,管道中维护了很多的处理器。
文章来源:https://blog.csdn.net/qq_44850917/article/details/135073129
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:chenni525@qq.com进行投诉反馈,一经查实,立即删除!