Netty I/O模型和线程模型

目录

1.概述

1.1 为什么使用Netty

1.2 Netty的优势

1.3 Netty的常见使用场景

2.Netty高性能的原因

2.1 I/O模型

2.1.1 阻塞IO

2.1.2 IO复用模型

2.2 线程模型

2.2.1 线程模型1:传统阻塞 I/O 服务模型

2.2.2 线程模型2:Reactor 模式

2.2.2.1 单 Reactor 单线程

2.2.2.2 单 Reactor 多线程

2.2.2.3 主从 Reactor 多线程


1.概述

Netty的官网:Netty: 首页

Netty是一个异步 事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端

  • Netty是由JBoss提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
  • 也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
  • Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

1.1 为什么使用Netty

  1. 直接使用 NIO 的时候,它的复杂的类库和API让人头大,例如需要我们熟练掌握NIO的几大核心内容:Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。
  2. 要编写出高质量的NIO程序需要熟练掌握多线程和网络编程技术,而这些工作量和难度都不小,例如客户端面临断连重连、网络闪断、半包卖写、失败缓存、网络拥塞和异常流的处理等等。
  3. NIO中有一些Bug:例如Epoll Bug,它会导致Selector 空轮询,最终导致CPU 100%。

1.2 Netty的优势

  • 设计:更优雅的设计简化了原生NIO中的复杂编程
  • 易用性:文档丰富的Javadoc、用户指南和示例
  • 性能:更好的吞吐量,更低的延迟;减少资源消耗;最小化不必要的内存拷贝(零拷贝--操作系统层面)
  • 安全:完整的SSL/TLS和StartTLS支持
  • 社区:社区活跃、不断更新

1.3 Netty的常见使用场景

  1. 互联网行业:在分布式系统中,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。典型的应用有:阿里分布式服务框架 Dubbo 使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。
  2. 游戏行业:无论是手游服务端还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈。非常方便定制和开发私有协议栈,账号登录服务器,地图服务器之间可以方便的通过 Netty 进行高性能的通信。
  3. 大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨节点通信,它的 Netty Service 基于 Netty 框架的二次封装实现。

2.Netty高性能的原因

Netty 作为异步事件驱动的网络框架,高性能之处主要来自于其 I/O 模型和线程处理模型I/O 模型决定如何收发数据,线程模型决定如何处理数据。

2.1 I/O模型

用什么样的通道将数据发送给对方,BIO、NIO 或者 AIO,I/O 模型在很大程度上决定了框架的性能

2.1.1 阻塞IO

传统阻塞型I/O(BIO)

  1. 每个请求都需要独立的线程完成数据的读写和业务处理
  2. 当客户端请求并发数较大时,需要创建大量线程来处理连接,系统资源占用较大
  3. 建立连接后,如果当前线程暂时没有数据可读,则线程就会阻塞在读取数据的操作上,造成线程资源浪费

2.1.2 IO复用模型

在 I/O 复用模型中,会用到 Select,这个函数也会使进程阻塞,但是和阻塞 I/O 所不同的是这个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作、多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。

Netty的非阻塞I/O的实现关键是基于I/O复用模型,这里用Selector 对象表示:

  1. 当线程从一个客户端SocketChannel进行读写数据时,若没有数据可用时,该线程可以执行其他任务。
  2. 线程通常将非阳塞I/O的空闲时间用于在其他通道上执行I/O操作,所以单独的线程可以管理多个输入和输出通道。
  3. 由于读写操作都是非阻塞的,这就可以充分提升I/O线程的运行效率,避免由于频繁I/O阻塞导致的线程挂起。
  4. 一个I/O线程可以并发处理N个客户端连接和读写操作,这从根本上解决了传统同步阻塞I/O一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。

传统的IO是面向字节流或字符流的,以流式的方式顺序地从一个stream中读取一个或多个字节,因此也就不能随意改变读取指针的位置。

在NIO中,抛弃了传统的IO流,而是引入Channel和Buffer的概念。在NIO中,只能从Channel中读取数据到Buffer中或将数据从Buffer中写入到channel。

基于Buffer操作不像传统IO的顺序操作,NIO中可以随意地读取任意位置的数据

2.2 线程模型

上面介绍了服务器如何基于I/O模型管理连接并获取输入数据,接着介绍一下决定服务器如何处理数据的线程模型。

2.2.1 线程模型1:传统阻塞 I/O 服务模型

特点:

  • 采用阻塞式I/O模型获取输入数据
  • 每个连接都需要独立的线程完成数据输入,业务处理,数据返回的完整操作

存在问题:

  • 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大
  • 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在读取数据(read)操作上,造成线程资源浪费

2.2.2 线程模型2:Reactor 模式

针对传统阻塞I/O服务模型的 2 个缺点,比较常见的有如下解决方案:

  • 基于I/O复用模型:多个连接共用一个阻塞对象,应用程序只需要在一个阻塞对象上等待,无需阻塞等待所有连接。当某条连接有新的数据可以处理时,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理。
  • 基于线程池复用线程资源:不必再为每个连接创建线程,将连接完成后的业务处理任务分配给线程进行处理,一个线程可以处理多个连接的业务。

而Reactor模式基本设计思想就是I/O复用结合线程池:

Reactor 模式,是指通过一个或多个输入同时传递给服务处理器的服务请求的事件驱动处理模式。

服务端程序处理传入多路请求,并将它们同步分派给请求对应的处理线程,Reactor 模式也叫 Dispatcher 模式。即I/O多路复用统一监听事件,收到事件后分发(Dispatch 给某进程),是编写高性能网络服务器的必备技术之一。

Reactor模式中有2个关键组成

  • Reactor:Reactor 在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对I/O事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人
  • Handlers:处理程序执行 I/O 事件要完成的实际事件,类似于客户想要与之交谈的公司中的实际负责人。Reactor 通过调度适当的处理程序来响应I/O事件,处理程序执行非阻塞操作

根据Reactor的数量和Handler的数量不同,有3种典型的实现

  1. 单 Reactor 单线程
  2. 单 Reactor 多线程
  3. 主从 Reactor 多线程

可以这样理解,Reactor 就是一个执行 while(true){selector.select();...} 循环的线程,会源源不断的产生新的事件,称作反应堆很贴切。

2.2.2.1 单 Reactor 单线程

其中Select 是前面I/O复用模型介绍的标准网络编程API,可以实现应用程序通过一个阻塞对象监听多路连接请求。

说明:

  1. Reactor 对象通过Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发
  2. 如果是建立连接请求事件,则由Acceptor 通过 Accept 处理连接请求,然后创建一个Handler 对象处理连接完成后的后续业务处理
  3. 如果不是建立连接事件,则Reactor 会分发调用连接对应的 Handler 来响应
  4. Handler 会完成Read一业务处理一Send的完整业务流程
  • 优点:模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成。
  • 缺点:性能问题,只有一个线程,无法完全发挥多核CPU 的性能。Handler 在处理某个连接上的业务时,整个进程无法处理其他连接事件,很容易导致性能瓶颈。当其中某个handler阻塞时,会导致其他所有的 client的 handler 都得不到执行,并目更严重的是,handler 的阻塞也会导致整个服务不能接收新的 client 请求(因为acceptor 也被阻塞了)。因为有这么多的缺陷,因此单线程Reactor 模型用的比较少。
  • 使用场景:客户端的数量有限,业务处理非常快速,比如Redis。
2.2.2.2 单 Reactor 多线程

说明:

  1. Reactor 对象通过Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发
  2. 如果是建立连接请求事件,则由Acceptor 通过 Accept 处理连接请求,然后创建一个Handler 对象处理连接完成后续的各种事件
  3. 如果不是建立连接事件,则Reactor 会分发调用连接对应的Handler 来响应
  4. Handler 只负责响应事件,不做具体业务处理,通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理
  5. Worker 线程池会分配独立的线程完成真正的业务处理,然后将响应结果发给 Handler 进行处理
  6. Handler 收到响应结果后通过Send 将响应结果返回给 Client
  • 优点:可以充分利用多核CPU的处理能力。
  • 缺点:
    • ①多线程数据共享和访问比较复杂。
    • ②Reactor 承担所有事件的监听和响应,在单线程中运行,高并发场景下容易成为性能瓶颈。
2.2.2.3 主从 Reactor 多线程

针对单 Reactor 多线程模型中,Reactor 在单线程中运行,高并发场景下容易成为性能瓶颈,可以让Reator在多线程中运行。

方案说明:

  1. Reactor 主线程 MainReactor 对象通过 Select 监控建立连接事件,收到事件后通过 Acceptor 接收,处理建立连接事件
  2. Acceptor 处理建立连接事件后,MainReactor 将连接分配给 SubReactor (Reactor 子线程) 进行处理
  3. SubReactor将连接加入连接队列进行监听,并创建一个Handler 用于处理各种连接事件
  4. 当有新的事件发生时,SubReactor 会调用连接对应的 Handler 进行响应
  5. Handler通过Read读取数据后,会分发给后面的 Worker 线程池进行业务处理
  6. Worker 线程池会分配独立的线程完成真正的业务处理,如何将响应结果发给 Handler 进行处理
  7. Handler 收到响应结果后通过 Send 将响应结果返回给 Client

优点:父线程与子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。

这种模型在许多项目中广泛使用,包括 Nginx主从Reactor 多进程模型,Memcached 主从多线程,Netty 主从多线程模型的支持。

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

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

相关文章

Javaweb之Vue组件库Element之Dialog对话框的详细解析

4.3.3 Dialog对话框 4.3.3.1 组件演示 Dialog: 在保留当前页面状态的情况下,告知用户并承载相关操作。其企业开发应用场景示例如下图所示 首先我们需要在ElementUI官方找到Dialog组件,如下图所示: 然后复制如下代码到我们的组件文件的templ…

线程基本方法

1。设置线程名 继承Thread类的线程,可以直接使用.setName()方法,设置线程名。也可以使用构造方法,需要注意java默认不继承构造方法,所以需要自己调用下父类的构造方法。 public class Demo {public static void main(String[…

每日一题:LeetCode-202.快乐数(一点都不快乐)

每日一题系列(day 06) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x1f50e…

基于 Python中的深度学习:神经网络与卷积神经网络

当下,深度学习已经成为人工智能研究和应用领域的关键技术之一。作为一个开源的高级编程语言,Python提供了丰富的工具和库,为深度学习的研究和开发提供了便利。本文将深入探究Python中的深度学习,重点聚焦于神经网络与卷积神经网络…

csgo/steam搬砖项目还能不能做,分享玩法思路

饰品市场持续下跌,CSGO搬砖还有搞头吗? CSGO是最具竞争力的第一人称射击游戏。玩这款游戏离不开里面的炫酷配件。Steam搬砖项目是基于CSGO游戏中的配件运动。蒸汽拆砖项目的原理是使用国外Steam平台的充值卡购买国际服务器的配件和设备,然后转…

【C++】继承(下) 单继承 | 多继承 | 菱形继承 | 继承和组合

一、单/多/菱形继承 1.单继承 当一个子类只有一个直接父类时,称这个继承关系为单继承。 2.多继承 一个子类有两个或以上直接父类时称这个继承关系为多继承。 举个实例:新老师进学校工作时,一般会作为助教老师,一边代课教书&am…

古埃及金字塔的修建

从理论上说,古埃及人完全有能力设计并建造出充满各种奇妙细节的胡夫金字塔,但后世还是不断涌现出质疑之声,原因倒也简单,那就是胡夫金字塔实在太大了。据推算,整座金字塔使用大约230万块巨石,总质量可达约5…

通俗易懂的spring Cloud;业务场景介绍 二、Spring Cloud核心组件:Eureka 、Feign、Ribbon、Hystrix、zuul

文章目录 通俗易懂的spring Cloud一、业务场景介绍二、Spring Cloud核心组件:Eureka三、Spring Cloud核心组件:Feign四、Spring Cloud核心组件:Ribbon五、Spring Cloud核心组件:Hystrix六、Spring Cloud核心组件:Zuul七…

MySQL 8 手动安装后无法启动的问题解决

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(…

Dockerfile讲解

Dockerfile 1. 构建过程解析2. Dockerfile常用保留字指令3. 案例3.1. 自定义镜像mycentosjava83.2. 虚悬镜像 4. Docker微服务实战 dockerfile是用来构建docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。 dockerfile定义了进程需要的一切东西&…

python之pyqt专栏6-信号与槽2

上一篇python之pyqt专栏5-信号与槽1-CSDN博客,我们通过信号与槽实现了点击Button,改变Label的文本内容。可以知道 信号是在类中定义的,是类的属性 槽函数是信号通过connect连接的任意成员函数,当信号发生时,执行与信号…

14 网关实战:网关聚合API文档

上节课介绍了网关层的认证鉴权,今天这节介绍一下网关层如何聚合API接口文文档。 为什么需要聚合API接口文档? 大型微服务系统模块众多,木谷博客系统就有9个,如果这些服务的接口地址没有一个统一,那么客户端将要保存每个服务的接口地址,这个肯定是不现实。 先来看一下A…

图书管理系统源码,图书管理系统开发,图书借阅系统源码四TuShuManager应用程序MVC控制器Controllers

Asp.net web应用程序MVC之Controllers控制器 Controller在ASP.NET MVC中负责控制所有客户端与服务器端的交互,并且负责协调Model与View之间的数据传递,是ASP.NET MVC的核心。 撰写Controller的基本要求: 1、Controller必须为公开类别; 2、Controller名称必须以Controller结…

【算法优选】 动态规划之路径问题——壹

文章目录 🎋前言🎋[不同路径](https://leetcode.cn/problems/unique-paths/)🚩题目描述:🚩算法思路:🚩代码实现 🎋[不同路径二](https://leetcode.cn/problems/unique-paths-ii/desc…

Go 基本语法

一、​​​​变量定义方法 var 定义变量 var 变量名 类型 表达式 var name string "Snail" var age int 21 var isOK bool bool 2.类型推导方式定义变量 a 在函数内部,可以使用更简略的: 方式声明并初始化变量**注意:**短变量只能用于声…

kaggle使用matplotlib画图中文乱码问题解决

import matplotlib import matplotlib.pyplot as plt myfont matplotlib.font_manager.FontProperties(fnamer/kaggle/input/flux-predict/STFANGSO/STFANGSO.TTF) train_corr df_train.corr() k 6 cols train_corr.nlargest(k,4G流量MB(1024)(兆字…

什么是可重入锁

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一份大厂面试资料《史上最全大厂面试题》,Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

2023最全的自动化测试入门基础知识(超详细~)

1)首先,什么是自动化测试? 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的过程一步步执行测试,得到实际结果与期望结果的比较。…

pdf加密文件解密(pdf文件解密小工具)

工具放在文章末尾! 1.pdf文件加密后会有很多使用权限的限制很不方便,只要是为了pdf的数据不被二次利用,未加密的pdf功能都是可以正常使用的 2.加密后的pdf使用权限会被限制部分 3.工具只能解决pdf编辑等加密情况,不能解决文件打…

浅谈UML的概念和模型之UML九种图

1、用例图(use case diagrams) 【概念】描述用户需求,从用户的角度描述系统的功能 【描述方式】椭圆表示某个用例;人形符号表示角色 【目的】帮组开发团队以一种可视化的方式理解系统的功能需求 【用例图】 2、静态图 类图&…