Netty线程模型 - Reactor 模式

简介: 我相信有很多人会对这个Reactor模式比较陌生,但是Netty这个名字大家都会比较熟悉,即使没有学习使用过,也会对它有所耳闻,它可以说是Java高性能网络编程的代名词。Reactor模式就是Netty线程模型设计的核心,本文我们就以Reactor模式入手,探究一下经典的设计。

1 前言

程序员的进阶之路上,不可避免的是对一些源码的学习,一些好的设计我们应该吸收到自己的代码,一些经典的设计就会形成设计模式。

2 概念

Reactor模式又被称为反应器模式,是一种为处理服务请求并发,提交到一个或者多个服务处理程序的事件设计模式。当请求抵达后,服务处理程序使用解多路分配策略,然后同步地派发这些请求至相关的请求处理程序。

Netty 的线程模型就是基于IO多路复用技术构建的,使用了异步驱动的Reactor 模式,可以很好的支持成百上千的 SocketChannel 连接。并且读写都是非阻塞的,可以充分提升运行效率 ,避免了阻塞式IO线程挂起的问题, 同时可以使一个线程支持对多个SocketChannel的读写操作, 从根本上解决了传统阻塞IO的一线程(进程)处理一连接的弊端。

Reactor是一种事件驱动机制,与普通函数调用的不同之处在于:

应用程序不是主动的调用某个API完成处理,应用程序需要提供相应的事件并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”,从而执行对应的处理逻辑。

3 为什么会使用Reactor模式

至于为什么会使用Reactor模式,那就不得不提一下多线程IO的致命缺陷,首先,介绍一下什么是多线程IO模式,多线程IO模式就是在一个无限循环中监听来自客户端的Sockect连接,如果有就会新建一个线程,去处理读写任务。这样的话就是一个连接对应一个线程,这样虽然可以在一定程度上解决并发问题,但是系统在每次建立连接都需要创建一个线程,对系统资源要求极高,当并发过大,系统是无法承受巨大的压力,线程的创建和销毁都是需要消耗资源的。然后基于事件驱动的Reactor模式,正好可以控制线程的数量,让同一个线程可以处理多个连接。

4 Reactor 模式的分类

  • 单线程Reactor

    在单个线程内,通过不同的事件触发Reactor调度不同的处理器,达到一个线程处理多个连接

    image.png

    特点:

    其中一个handler 阻塞,所有连接都会被阻塞,线程被阻塞后,系统也不能去接受新的连接。因此

  • 多线程Reactor

    多线程模型将监听独立出来,保证系统可以正常建立连接,借助线程池优化事件处理,让串行处理,变为并行处理

    image.png

  • 主从多线程Reactor

    此模式将Reactor分为两部分,BossReactor负责监听accept新连接,然后将建立的socket通过多路复用器(Acceptor)分派给WorkReactor。WorkReactor负责多路分离已连接的socket,读写网络数据;业务处理功能,其交给worker线程池完成。通常,BossReactor线程数量为1-2个,WorkReactor个数上一般为CPU个数的二倍或者与CPU个数相同。

    image.png

Netty 支持多种模式的Reactor

5 Reactor 模式的优缺点

5.1. 优点

1)响应速度快,基于事件驱动,尽可能避免阻塞(Reactor模式依然是同步);

2)借助线程池,优化线程/进程的切换创建开销;

3)高可复用性,Reactor模式与具体事件处理逻辑无关,具有很高的复用性;

5.2. 缺点

1) Reactor模式在IO读写数据时,使用同一个线程处理多个连接的读写,当某些读写的数据过大时,容易影响其他连接的读写效率。所以Reactor模式并不是在所有情况下都适用的,它更适用于处理小而多的数据传输。网络传输的数据过大时,采用传统的一线程处理一连接更适用。

2)Reactor模式需要底层的Synchronous Event Demultiplexer(IO多路复用技术)支持,比如Java中的Selector支持,linux系统的select、poll、epoll支持。

3)Reactor模式,相对比较复杂,因而具有一定的学习门槛。

目录
相关文章
|
11月前
|
负载均衡 算法 安全
基于Reactor模式的高性能网络库之线程池组件设计篇
EventLoopThreadPool 是 Reactor 模式中实现“一个主线程 + 多个工作线程”的关键组件,用于高效管理多个 EventLoop 并在多核 CPU 上分担高并发 I/O 压力。通过封装 Thread 类和 EventLoopThread,实现线程创建、管理和事件循环的调度,形成线程池结构。每个 EventLoopThread 管理一个子线程与对应的 EventLoop(subloop),主线程(base loop)通过负载均衡算法将任务派发至各 subloop,从而提升系统性能与并发处理能力。
539 3
|
8月前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
507 2
|
安全 Java 调度
Netty源码—3.Reactor线程模型二
本文主要介绍了NioEventLoop的执行总体框架、Reactor线程执行一次事件轮询、Reactor线程处理产生IO事件的Channel、Reactor线程处理任务队列之添加任务、Reactor线程处理任务队列之执行任务、NioEventLoop总结。
|
安全 Java
Netty源码—2.Reactor线程模型一
本文主要介绍了关于NioEventLoop的问题整理、理解Reactor线程模型主要分三部分、NioEventLoop的创建和NioEventLoop的启动。
|
12月前
|
机器学习/深度学习 监控 算法
局域网行为监控软件 C# 多线程数据包捕获算法:基于 KMP 模式匹配的内容分析优化方案探索
本文探讨了一种结合KMP算法的多线程数据包捕获与分析方案,用于局域网行为监控。通过C#实现,该系统可高效检测敏感内容、管理URL访问、分析协议及审计日志。实验表明,相较于传统算法,KMP在处理大规模网络流量时效率显著提升。未来可在算法优化、多模式匹配及机器学习等领域进一步研究。
300 0
|
网络协议 安全 Java
Netty线程模型详解
1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 时间回到十几年前,那时主流的CPU都还是单核(除了商用高性能的小机),CPU的核心频率是机器最重要的指标之一。 在Java领域当时比较流行的是单线程编程,对于CPU密集型的应用程序而言,频繁的通过多线程进行协作和抢占时间片反而会降低性能。 1.1.2. 多线程 随着硬件性能的提
1915 0
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
14063 1
|
算法 Java 容器
Netty源码—4.客户端接入流程
本文主要介绍了关于Netty客户端连接接入问题整理、Reactor线程模型和服务端启动流程、Netty新连接接入的整体处理逻辑、新连接接入之检测新连接、新连接接入之创建NioSocketChannel、新连接接入之绑定NioEventLoop线程、新连接接入之注册Selector和注册读事件、注册Reactor线程总结、新连接接入总结
|
编解码 安全 Java
Netty源码—1.服务端启动流程
本文主要介绍了服务端启动整体流程及关键方法、服务端启动的核心步骤、创建服务端Channel的源码、初始化服务端Channel的源码、注册服务端Channel的源码、绑定服务端端口的源码、服务端启动流程源码总结。
|
消息中间件 Oracle Dubbo
Netty 源码共读(一)如何阅读JDK下sun包的源码
Netty 源码共读(一)如何阅读JDK下sun包的源码
366 1