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模式,相对比较复杂,因而具有一定的学习门槛。

目录
相关文章
|
3月前
|
编解码 网络协议 API
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
|
27天前
|
并行计算 JavaScript 前端开发
单线程模型
【10月更文挑战第15天】
|
29天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
17 1
|
2月前
|
消息中间件 存储 NoSQL
剖析 Redis List 消息队列的三种消费线程模型
Redis 列表(List)是一种简单的字符串列表,它的底层实现是一个双向链表。 生产环境,很多公司都将 Redis 列表应用于轻量级消息队列 。这篇文章,我们聊聊如何使用 List 命令实现消息队列的功能以及剖析消费者线程模型 。
98 20
剖析 Redis List 消息队列的三种消费线程模型
|
1月前
|
NoSQL Java Redis
Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
本文通过一个简单的单线程Reactor模式的Java代码示例,展示了如何使用NIO创建一个服务端,处理客户端的连接和数据读写,帮助理解Reactor模式的核心原理。
32 0
Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
|
1月前
|
NoSQL Redis 数据库
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
本文解释了Redis为什么采用单线程模型,以及为什么Redis单线程模型的效率和速度依然可以非常高,主要原因包括Redis操作主要访问内存、核心操作简单、单线程避免了线程竞争开销,以及使用了IO多路复用机制epoll。
49 0
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
|
1月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
2月前
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解
|
1月前
|
消息中间件 NoSQL 关系型数据库
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
25 0
|
3月前
|
存储 Kubernetes NoSQL
Tair的发展问题之Tair在适配不同的存储介质时对于线程模型该如何选择
Tair的发展问题之Tair在适配不同的存储介质时对于线程模型该如何选择