Java 面试宝典:请说下你对 Netty 中Reactor 模式的理解

大家好,我是大明哥,一个专注「死磕 Java」系列创作的硬核程序员。
本文已收录到我的技术网站:https://skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经


回答

Reactor 模式是一种高效处理并发网络事件的设计模式,它通过一组 Reactor 线程(事件循环组)来监听和分发网络事件(如连接、读取、写入),并结合非阻塞 I/O 和用户定义的事件处理器来实现。

Reactor 模式的核心思想是把响应 IO 事件和业务处理进行分离。它通过一个或者多个线程监听 I/O 事件,将已经准备就绪的 I/O 事件分发给业务线程去处理。其核心组件有三个:

  • Reactor 组件:这是 Reactor 模式的核心。Reactor 组件负责监听和分发事件。在一个无限循环中,它等待 I/O 事件的到来,然后将这些就绪的 I/O 事件快速分发给相应的处理程序。在 Netty 中,这通常对应于 EventLoop 组件。
  • Acceptor 组件:请求连接器。Reactor 组件接收到 client 连接事件后,会将其转发给 Acceptor,Acceptor 则会接受 Client 的连接,建立对应的Handler,并向 Reactor注册此Handler。
  • Handler 组件:求处理器,负责具体事件的处理程序。当 Reactor 组件将事件分发给它们时,它们负责处理这些事件。在 Netty 中,这些处理器通常是用户自定义的 ChannelHandler,用于处理特定的事件,如接收数据、异常处理等。

在 Reactor 模式中,主要有三种模型:

  • 单 Reactor 单线程模型。
  • 多线程 Reactor 模型。
  • 主从多 Reactor 多线程模型。

详解

单 Reactor 单线程模型

单线程 Reactor 模型,即所有的 I/O 处理和业务逻辑都在同一个线程(即 Reactor 线程)中执行。

处理流程如下

  • Reactor 通过 Select 监听 I/O 事件,收到事件后由 Dispatch 来分发。
  • 如果是建立连接事件,则由 Acceptor 进行处理,Acceptor 会通过 accept 方法获取链接,并创建一个 Handler 对象来处理后续的响应事件。
  • 如果不是建立连接事件,则将该事件交由当前连接的 Handler 来处理。Handler 按照 read —> 业务处理 —> send 的流程来完成整个事件。

优点

该模型是将所有处理逻辑放在一个线程中实现,模型简单,没有多线程、进程通信、竞争的问题

缺点

由于只有一个线程,无法充分利用多核CPU 的性能,性能堪忧。同时Handler 在处理某个连接上的业务时,整个进程无法处理其他连接事件,很容易导致性能瓶颈。

还有一个比较严重的可靠性问题,如果线程意外终止,或者进入死循环,则会导致整个线程都无法接受和处理事件了,造成节点故障。

单 Reactor 多线程

单线程存在性能瓶颈,那我们就引入多线程方案。

多线程 Reactor 模型,它将处理 I/O 就绪时间的线程和处理业务逻辑 Handler的线程分开了,每个 Handler 由一个独立的线程来处理。

Reactor 接受请求后,根据请求类型来进行分发,分发逻辑与单Reactor单线程模型一样,不同之处在于单 Reactor 多线程 的 Handler 不再进行业务处理了,它只负责接受和发送:Handler接受数据后,会将数据发送给 Worker 线程池中的线程处理,该线程才是处理业务的真正线程,线程将业务处理完成后,将数据发送给 Handler,由 Handler 再 send 出去。

优点

由于 Handler 使用了多线程模式,则可以利用充分利用CPU的性能。

缺点

Handler使用多线程模式,则会涉及到数据共享的问题,需要考虑互斥,实现肯定比单Reactor单线程模式复杂一些。但是在实际开发过程中,我们一般都会让业务处理是无状态的,一般不会用共享变量,所以在大多数业务场景中 Handler 的开发并不会复杂太多。

单Reactor,一个线程处理事件监听、分发、响应,对于高并发场景,容易造成性能瓶颈。

多 Reactor 多线程模型

单Reactor多线程模式虽然解决了 Handler 单线程的性能问题,但是 Reactor 还是单线程的,对于高并发场景还是会有性能瓶颈,所以需要对 Reactor 也调整为多线程模式

  • 主线程中的 MainReactor 对象通过 select 监听事件,接收到事件后通过 Dispatch 进行分发,如果事件类型为建立连接则将事件分发给 Acceptor 进行连接建立
  • 如果收到的事件不是连接,则他将事件分发个某个 SubReactor,SubrReactor 将连接加入到连接队列进行监听,并创建 Handler 进行各种事件处理
  • 如果有新的事件发生,SubReactor 则会调用当前连接的 Handler 来进行处理。Handler 通过 read 读取数据后,将数据发送给 Worker 线程进行处理,Worker 线程池则会分配线程进行业务处理,处理完成后返回结果,Handler 接受结果后,通过 send 发送给客户端

优点

该模式主线程和子线程分工明确,主线程只负责接收新连接,子线程负责完成后续的业务处理,同时主线程和子线程的交互也很简单,子线程接收主线程的连接后,只管业务处理即可,无须关注主线程

缺点

模型复杂。

这种模式适用于高并发场景,广泛运用于各种项目中,如大名鼎鼎的Netty。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/784730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IntelliJ IDEA】运行测试报错解决方案(附图)

IntelliJ IDEA 版本 2023.3.4 (Ultimate Edition) 测试报错信息 命令行过长。 通过 JAR 清单或通过类路径文件缩短命令行,然后重新运行 解决方案 修改运行配置,里面如果没有缩短命令行,需要再修改选项里面勾选缩短命令行让其显示&#x…

STM32八种I/O口模式

STM32八种I/O口模式 文章目录 STM32八种I/O口模式前言一、stm32八种I/O类型二、区别1.模拟输入2.浮空输入3.上拉输入4.下拉输入5.推挽输出6.开漏输出7.复用推挽输出8.复用推挽输出 总结 前言 作为两年嵌入式软件攻城狮,还没仔细去理解过STM32的GPIO的八种使用模式&…

5G无线接入网和接口协议

**部分笔记** 4.3无线协议架构 NR无线协议分为两个平面:用户面和控制面。 用户面(UP):协议栈及用户数据采用的协议 控制面(Control Plane,CP)协议栈即系统的控制信令传输采用的协议簇。 虚线标注的是信令数据的流向。一个UE在…

宁波ISO22000认证:食品安全管理的国际标杆

🍎宁波ISO22000认证:🍉食品安全管理的国际标杆 随着全球化🌍的不断深入,食品安全问题👨‍👩‍👧越来越受到人们的👩‍👩‍👦‍👦关注…

Servlet Response的常用方法 缓存和乱码处理

前言 Servlet Response相关的信息,在service方法中使用的是HttpServletResponse,它继承自ServletResponse,扩展了Http协议相关的内容,下面简单记录一下它的基本用法。 一、response组成内容 以下是一个常见response响应的内容&…

Redis超好用可视化工具--RedisInsight工具安装

RedisInsight 保姆级安装 RedisInsight 是Redis官方出品的可视化redis管理工具,具有很强大的功能。接下来,让我们一起去完成这款炫酷工具的安装 1. RedisInsight 下载 RedisInsight 官方下载地址,https://redis.io/docs/connect/insight/ …

springboot在线学习做题答题统计系统-可视化分析系统

系统阐述的是使用可视化的学习系统的设计与实现,对于java、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计,描述,实现和分析与测试方面来表明开发的过程。开发中使用了 springboot框架和MySql数据库技术搭建系统的整体架构。…

CleanMyMac X2024专业免费的国产Mac笔记本清理软件

非常高兴有机会向大家介绍CleanMyMac X 2024这款专业的Mac清理软件。它以其强大的清理能力、系统优化效果、出色的用户体验以及高度的安全性,在Mac清理软件市场中独树一帜。 CleanMyMac X2024全新版下载如下: https://wm.makeding.com/iclk/?zoneid49983 一、主要…

挖一挖:PostgreSQL Java里的double类型存储到varchar精度丢失问题

前言 大概故事是这样的,PostgreSQL数据库,表结构: create table t1(a varchar);然后使用标准的Java jdbc去插入数据,其基本代码如下: import java.sql.*; public class PgDoubleTest {public static void main(Stri…

C语言TCP服务器模型 : select + 多线程与双循环单线程阻塞服务器的比较

观察到的实验现象: 启动三个客户端: 使用双循环阻塞服务器:只能accept后等待收发,同时只能与一个客户端建立连接,必须等已连接的客户端多次收发 明确断开后才能与下个客户端连接 使用IO多路复用select:可以同时接收所有的连接请求,并且连接状态一直是存活的,直到客户端关闭连…

53 v-bind 和 v-model 的实现和区别

前言 这个主要的来源是 偶尔的情况下 出现的问题 就比如是 el-select 中选择组件之后, 视图不回显, 然后 model 不更新等等 这个 其实就是 vue 中 视图 -> 模型 的数据同步, 我们通常意义上的处理一般是通过 模型 -> 数据 的数据同步, 比如 我们代码里面更新了 model.…

C#/.NET/.NET Core优秀项目和框架2024年3月简报

前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学…

变更控制、变更类型

目录 1、变更控制 2、变更类型 1、变更控制 在软件开发过程中会有许多变更,如代码、配置、SQL、基线、构建版本、发布版本等变更。对于变更都要有一个控制机制,以保证所以变更都是可控的、可跟踪的、可重现的。对变更进行控制的机构称为变更控制委员会…

爬虫(Web Crawler)介绍与应用

## 摘要 本文将介绍什么是爬虫(Web Crawler)以及其在信息抓取、数据分析等领域的应用。我们将深入探讨爬虫的工作原理、设计特点以及开发过程中需要考虑的关键问题。 ## 一、什么是爬虫 爬虫是一种自动化程序或脚本,用于从互联网上抓取信息…

[HackMyVM]靶场Pipy

难度:easy kali:192.168.56.104 靶机:192.168.56.141 端口扫描 ┌──(root㉿kali2)-[~/Desktop] └─# nmap 192.168.56.141 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-31 20:10 CST Nmap scan report for 192.168.56.141 Host is up (0.00…

Vitepress部署到GitHub Pages,工作流

效果: 第一步: 部署 VitePress 站点 | VitePress 执行 npm run docs:build,npm run docs:preview,生成dist文件 第二步: 手动创建.gitignore文件: node_modules .DS_Store dist-ssr cache .cache .temp *…

Python100个库分享第5个—fuzzywuzzy

目录 专栏导读库介绍安装fuzz模块用法1:简单匹配(Ratio)fuzz模块用法2:推荐使用—非完全匹配(Partial Ratio)fuzz模块用法3:Token Sort Ratio)process模块extract提取多条数据extrac…

55 npm run serve 和 npm run build 的分包策略

前言 这里我们来看一下 vue 这边 打包的时候的一些 拆分包的一些策略 我们经常会使用到 npm run build 进行服务的打包 然后 打包出来的情况, 可能如下, 可以看到 chunk-vendors 是进行了包的拆分, 我们这里就是 来看一下 这里 npm run build 的时候的, 一个分包的策略 测试…

Verilog基础【一】

文章目录 1.1 第一个verilog设计1.2 Verilog 简介1.3 Verilog环境搭建1.4 Verilog 设计方法设计方法设计流程 2.1 Verilog 基础语法格式注释标识符与关键字 2.2 Verilog 数值表示数值种类整数数值表示方法实数表示方法十进制:科学计数法: 字符串表示方法…

ubuntu23.10配置RUST开发环境

系统版本: gcc版本 下载rustup安装脚本: curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh下载完成后会自动执行 选择默认安装选项 添加cargo安装目录到环境变量 vim ~/.bashrc 默认已添加 使用环境变量立即生效 source ~/.bashrc 执行rust开发环境,在终端输入…