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

news2024/12/24 2:06:50

大家好,我是大明哥,一个专注「死磕 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.coloradmin.cn/o/1559801.html

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

相关文章

新手使用GIT上传本地项目到Github(个人笔记)

亲测下面的文章很有用处。 1. 初次使用git上传代码到github远程仓库 - 知乎 (zhihu.com) 2. 使用Git时出现refusing to merge unrelated histories的解决办法 - 知乎

五、Yocto集成QT5(基于Raspberrypi 4B)

Yocto集成QT5 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第五篇文章: 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi 4B) 三、Yocto创建自定义的layer和image 四、Yocto创建静态IP和VLAN 本章节实操代码请查看github仓库&…

yolov5 v7.0打包exe文件,使用C++调用

cd到yolo5文件夹下 pyinstaller -p 当前路径 -i logo图标 detect.py问题汇总 运行detect.exe找不到default.yaml 这个是yolov8里的文件 1 复制权重文件到exe所在目录。 2 根据报错提示的配置文件路径,把default.yaml复制放到相应的路径下。(缺少相应…

Linux的开发工具(二):编译器gcc/g++与Linux项目自动化构建工具-Makefile

Linux的编译器-gcc/g 基本概念:gcc是专门用来编译c语言的,g可以编译c或c语言 问题一:gcc有时候为什么不能编译带有for循环的c语言源文件? 答:gcc版本过低会不支持for循环等c99标准下的内容 解决方式:gcc…

Spring定义Bean对象笔记

前言:面向对象语言最基本的元素就是对象,在Spring中把对象都封装为一个个的Bean,即通过Bean容器来管理对象;那么接下来我们看下在Spring中如何创建所需要的Bean。 一、环境准备 员工类 package com.xlb.bean;public class Empl…

在 C#和ASP.NET Core中创建 gRPC 客户端和服务器

关于gRPC和Google protobuf gRPC 是一种可以跨语言运行的现代高性能远程过程调用 (RPC) 框架。gRPC 实际上已经成为 RPC 框架的行业标准,Google 内外的组织都在使用它来从微服务到计算的“最后一英里”(移动、网络和物联网)的强大用例。 gRP…

数据结构——二叉树——堆

前言: 在前面我们已经学习了数据结构的基础操作:顺序表和链表及其相关内容,今天我们来学一点有些难度的知识——数据结构中的二叉树,今天我们先来学习二叉树中堆的知识,这部分内容还是非常有意思的,下面我们…

重读 Java 设计模式: 深入探讨原型模式,灵活复制对象

引言 在软件开发中,经常会遇到需要创建对象的情况。有时候,我们希望创建一个新的对象,但又不想通过传统的构造方法来创建,而是希望通过复制一个现有对象的方式来创建新的对象。这时,原型模式就能派上用场了。原型模式…

【51单片机入门记录】A2普中开发板实验课例程

一、开发板原理图 二、例程 &#xff08;1&#xff09;呼吸灯 #include <STC89C5xRC.H> #include<intrins.h>unsigned int PWM_wanttime0; //想要多长时间改变的占空比一次 unsigned int Breath_wanttime0; //想要多长时间改变呼气或者吸气的值时间 unsigned …

Android Studio 新建aar包

有几个注意事项 第一是注意是选择Android library这个包注意moudle name不能包含apk这三个字符

动手学机器学习双线性模型+习题

在数学中&#xff0c;双线性的含义为&#xff0c;二元函数固定任意一个自变量时&#xff0c;函数关于另一个自变量线性 矩阵分解 设想有N个用户和M部电影&#xff0c;构建一个用户画像库&#xff0c;包含每个用户更偏好哪些类型的特征&#xff0c;以及偏好的程度。假设特征的个…

0.5米多光谱卫星影像在农业中进行地物非粮化、非农化监测

一、引言 随着科技的发展&#xff0c;卫星遥感技术已经成为了农业领域中重要的数据来源。其中&#xff0c;多光谱卫星影像以其独特的优势&#xff0c;在农业应用中发挥着越来越重要的作用。本文将重点探讨0.5米加2米多光谱卫星影像在农业中的应用。 二、多光谱卫星影像概述 多…

ESP8266 WiFi物联网智能插座—上位机软件实现

1、软件架构 上位机主要作为下位机数据上传服务端以及节点调试的控制端&#xff0c;可以等效认为是专属版本调试工具。针对智能插座协议&#xff0c;对于下位机进行可视化监测和管理。 软件技术架构如下&#xff0c;主要为针对 Windows 的PC 端应用程序&#xff0c;采用WPF以及…

Mock.js的基本使用

mock顾名思义&#xff0c;就是模拟的意思&#xff0c;它模拟什么呢&#xff1f;假设我们在开发的过程中&#xff0c;我们需要使用到接口&#xff0c;但是后端接口并没有完善&#xff0c;那么我们就可以使用到mock.js&#xff0c;它可以随机生成数据&#xff0c;拦截AJAX请求&am…

壁纸小程序Vue3(分类页面和用户页面基础布局)

1.配置tabBar pages.json "tabBar": {"color": "#9799a5","selectedColor": "#28B389","list": [{"text": "推荐","pagePath": "pages/index/index","iconPath&quo…

网络安全-内网渗透2

一、MIC 将我们上次未描述完的MIC在这里详细解释一下 咱们所抓的第二个包会给返回一个服务端的challenge 之后服务器回包的第三个包会回复一个client challenge 所以咱们客户端和服务端现在分别有两个challenge&#xff0c;相当于客户端和服务端互相交换了一下challenge 因此…

《深度学习入门之PyTorch》书籍阅读笔记

《深度学习入门之PyTorch》书籍阅读笔记 ISBN 978-7-121-32620-2 多层全连接神经网络 Pytorch基础 Tensor张量 是一个多维矩阵&#xff0c;pytorch的tensor可以和numpy的ndarray相互转换&#xff0c;但numpy的ndarray只能在CPU上运行。不同数据类型的Tensor&#xff0c;t…

nginx的https与动态负载均衡

nginx的https 证书可以根据你的域名和服务器服务商去进行签发 , 比如 : 阿里云 腾讯云 百度云 华为云等 这里使用的是腾讯云 : 下载证书 : 选择 nginx: 下载之后传递到服务器上。 下面开始配置nginx的https: 1. 解压下载的证书包 cd /etc/ssl unzip xxcc.dwa_nginx.zip mv…

JMeter基础用法和测试WebSocket请求

目录 JMeter websocket插件安装测试接口的编写添加测试线程组创建取样器创建WebSocket连接创建循环控制器创建WebSocket request-response Sampler创建固定定时器 正则匹配上一个请求的数据做为当前请求参数正则编写使用匹配值 CSV文件读取参数添加汇总报告和结果树 JMeter web…

zookeeper如何管理客户端与服务端之间的链接?(zookeeper sessions)

zookeeper客户端与服务端之间的链接用zookeeper session表示。 zookeeper session有三个状态&#xff1a; CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY, CLOSED, AUTH_FAILED, NOT_CONNECTED&#xff08;start时的状态&#xff09; 1、CONNECTING 。 表明客户…