当前位置: 首页 > news >正文

Netty详解-01

Netty

讲解常用io模型及相关概念(包括IO基本概念、BIO、NIO、Epoll、Redis单线程模型、Netty线程模型、Reactor模型)、netty基本概念、核心组件

IO

IO概念

阻塞IO/非阻塞IO
  1. 阻塞IO:发起IO后线程挂起,直到IO完成才能继续其他操作
  2. 非阻塞IO:发起IO后线程不挂起,可立即执行其他操作,无需等待IO完成
同步IO/异步IO
  1. 同步IO:IO操作需主动检查完成状态,且需自行读取/写入数据
  2. 异步IO:IO操作由操作系统后台完成,完成后主动推送数据并回调通知

BIO模型

java.io包

基于流模型实现

传统IO,同步并阻塞的IO模式

提供:

  • File抽象
  • 输入输出流等

BIO基础示例

BIO中,相当于一个线程只能处理单个连接,虽然我们可以让当前线程通过new其他线程去帮处理连接,但可能导致线程数量太多,虽然我们可以限定线程池,但是就会出现同样的性能不足问题,即当线程用完后,依旧阻塞

BIO线程切换频繁,且阻塞消耗大量资源

BIO就是死等,来连接后一定要当时就处理好,才去管其他连接

/*** BIO TCP 服务端(阻塞式)* 特点:单线程,一次只能处理一个客户端连接,处理完一个再接收下一个*/
public class BioTcpServer {public static void main(String[] args) {int port = 8888; // 监听端口try (// 1. 创建 ServerSocket,绑定端口ServerSocket serverSocket = new ServerSocket(port)) {System.out.println("BIO 服务端启动,监听端口:" + port);while (true) {// 2. 阻塞等待客户端连接(accept() 阻塞,直到有客户端连接)Socket clientSocket = serverSocket.accept();System.out.println("客户端连接成功:" + clientSocket.getInetAddress());// 3. 处理客户端请求(阻塞读写)handleClient(clientSocket);}} catch (IOException e) {e.printStackTrace();}}/*** 处理客户端通信(阻塞式读/写)*/private static void handleClient(Socket clientSocket) {try (// 获取客户端输入流(读客户端数据)BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));// 获取客户端输出流(向客户端写数据)BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))) {String msg;// 阻塞读取客户端消息(readLine() 阻塞,直到客户端发送数据)while ((msg = reader.readLine()) != null) {System.out.println("收到客户端消息:" + msg);// 向客户端回复消息(阻塞写入)String response = "服务端已收到:" + msg + "\n";writer.write(response);writer.flush(); // 刷新缓冲区,确保消息发送// 约定:客户端发送 "exit" 则断开连接if ("exit".equals(msg)) {System.out.println("客户端断开连接:" + clientSocket.getInetAddress());break;}}} catch (IOException e) {e.printStackTrace();} finally {try {clientSocket.close(); // 关闭客户端连接} catch (IOException e) {e.printStackTrace();}}}
}

NIO模型

java1.4引入,java.nio包

面向缓冲,基于通道

同步非阻塞的IO模式

一个线程处理多个通道channel

提供:

  • Channel
  • Selector
  • Buffer等

基础NIO

基础NIO中,NIO不会阻塞等待连接,而是当连接到来后,如果没有数据,则不处理该连接,直接保存当前连接,然后就去管理下一个连接。后续再轮询处理前面保存的所有连接,轮到之前的连接且数据就位时,就可以处理该连接

但在基础NIO中,如果将所有的连接都存起来,后续再轮询,会导致很多可能并不需要io操作的连接被轮询,导致浪费

基础NIO就是再BIO基础上,不等,连接来了我无法处理就存起来,后面统一处理

到了这里,你可能会想到,如果数据已经就位了,但NIO直到下次轮循到对应的连接才能处理,这样的客户等待的事件似乎会比BIO长一点

然而:

BIO 中客户等待时间 = 「数据传输时间」 + 「线程调度时间」 + 「IO 阻塞浪费时间」(线程池满了,需要等待线程)

NIO 中客户等待时间 = 「数据传输时间」 + 「轮询等待时间」 + 「IO 处理时间」

IO阻塞不可控制,且调度消耗很大,因此,极大情况都会比BIO快

简而言之

IO操作是茶水

BIO是客户一来,我就去服务,即使茶水没好,我也等着;多个客人我就安排多个人去等茶水

NIO是客户一来,我先不管,我先让所有的客户坐着等会,然后等茶水,哪个客户的茶好了,我就去服务谁

NIO多路复用

由于基础NIO可能轮询所有连接(包括不需要io的连接,也就是不需要喝茶的客户),因此就出现了多路复用,也就是将刚刚都需要被处理的连接中,筛选出需要用到io操作的连接,将这些连接保存到另一个位置,后续轮询则只用处理这些io

NIO多路复用即在基础NIO基础上,只轮询需要io的连接,避免轮询不需要io的连接

如果你对两种连接不理解:

  1. 不需要io的连接:

    微信:你和朋友聊天,发送一条消息后,连接不会关闭,而是保持空闲,直到你发下一条消息,空闲情况下就是不需要io的连接

  2. 需要io的连接(需要被NIO处理的):

    一旦你发送信息,当前连接就是需要io的连接

因此,其实NIO轮询中的连接中,是会不断加入新连接,且对于空闲连接不进行轮询处理,但也不会踢出空闲连接,因为要确保该空闲连接突然有io请求到来,此时要能快速响应

Epoll事件轮询模型

Linux 操作系统的多路复用机制,是 NIO 在 Linux 下的底层实现之一

epoll 就是Linux下的 NIO 中 Selector(多路复用器)的 “底层发动机”,负责高效监控大量连接,筛选出 “有 IO 事件就绪” 的连接,让 NIO 不用轮询所有连接就能精准处理有效请求

Redis线程模型

更加极致的NIO

单线程 + IO多路复用

你是否回想那为什么java中不也极致的NIO,就一个单线程呢

因为redis基于内存,他快,而java可能调用各种数据库MySQL等,而且还要处理各种复杂的后端业务逻辑,因此处理速度较慢,一旦使用单线程,java项目的效率将会极低,因为一旦查询Mysql慢了几秒,那其他所有的请求都要等着

而redis内存操作很快,单线程还避免了线程切换开销,因此更适用

Netty线程模型

NIO可以单线程也可以多线程,像我们java后端可能接触到的Tomcat、netty就是基于多线程的NIO

Netty 线程模型的本质是通过 BossGroup 处理连接、WorkerGroup 处理 IO、业务线程池处理耗时逻辑,既保留了 NIO 的高效性,又解决了 Java 复杂业务的阻塞问题,成为 Java 高并发网络编程(如 IM、电商、网关)的首选框架

EventLoop中会提到BossGroup、WorkerGroup

简单来说,netty基于NIO,但如果我们直接和NIO打交道,来编写网络通信应用,则会很困难,而netty帮我们解决了很多问题,且帮我封装好了大量API,方便我们开发网络应用程序

例如:

  1. 原生 NIO 要手动处理:Selector 空轮询、缓冲区溢出、半包 / 粘包、断线重连等一堆细节问题,稍不注意就出 bug
  2. 原生 NIO 没有现成的编码解码、心跳检测、流量控制等常用功能,都要自己写

Reactor模型

“Reactor” 翻译过来是 “反应器”,核心作用是:监控所有连接的 IO 事件(新连接、读 / 写数据),然后分发任务给对应的处理逻辑

Reactor是设计模式,基于 Selector/epoll 这类多路复用技术,才得以落地实现高并发事件处理

指导如何用 NIO 构建高效线程模型

Reactor 模型根据「Reactor 数量」和「线程数量」,分3种变体:

  1. 单线程 Reactor 模型(最简单,对应原生 NIO 基础用法)
  2. 多线程 Reactor 模型(优化单线程瓶颈,对应原生 NIO 手动多线程)
  3. 主从 Reactor 模型(工业级最优解,对应 Netty 线程模型)

总结

BIO太拉,NIO是机制,Reactor是设计模式,redis、netty线程模型基于nio以及reactor的设计模式,epoll是linux下nio实现

Netty

概念

Netty是:NIO客户端服务器框架,用于快速轻松地开发网络应用程序(如协议服务器、客户端),简化网络编程(如TCP、UDP套接字服务器)

一套框架就能搞定 “服务端监听连接、客户端发起连接” 的全场景

套接字服务器:Netty 封装后的 “底层网络服务基座”,是基于 TCP/UDP 协议的 “通信入口”,负责监听端口、接收客户端连接、底层数据传输

协议服务器:在 “套接字服务器” 基础上,集成了特定应用层协议(Http、WebSocket等)解析能力的服务器

客户端:主动向服务器发起连接、遵循相同协议与服务器通信的 “终端程序”,是服务器的交互方

套接字服务器:相当于 “开通了电话线路”,能接打电话,但不知道对方说的是什么语言

协议服务器:相当于 “确定用中文交流”,接电话后能听懂对方说的话(解析 HTTP 请求),也能用中文回应(返回 HTTP 响应)

客户端(浏览器):相当于 “打电话的人”,用中文(HTTP 协议)通过电话线路(TCP)和对方交流

应用层协议

TCP

“面向连接、可靠传输” 的传输层协议(会保证数据不丢失、不重复、按顺序到达)

协议核心用途传输层依赖通信方式(单向 / 双向)连接特性核心区别 & 关键细节
HTTP网页访问、API 接口调用TCP单向(客户端请求→服务器响应)原本短连接(HTTP/1.1 支持长连接 keep-alive1. 文本协议(如 GET /api HTTP/1.1);2. 无状态(默认不存客户端上下文,需 Cookie/Session);3. 核心场景:前后端数据交互、文件下载(非大文件最优)
FTP大文件批量传输TCP双向(命令 + 数据双通道)长连接(全程保持连接)1. 双端口工作:21 端口传命令(如 “上传文件”)、20 端口传数据;2. 支持断点续传、文件权限管理;3. 核心场景:服务器文件批量同步、大文件传输(比 HTTP 更高效)
SMTP邮件传输TCP单向(发件服务器→收件服务器)长连接(传输完邮件才断开)1. 专门用于 “邮件发送”(接收邮件用 POP3/IMAP 协议);2. 支持附件、邮件头(收件人 / 主题)解析;3. 核心场景:邮箱客户端发邮件(如 Outlook 用 SMTP 发邮件)
WebSocket即时双向交互TCP双向(客户端↔服务器实时推送)长连接(一次握手后持续通信)1. 基于 HTTP 握手(先发送 HTTP 请求升级协议),后续用二进制帧传输;2. 低延迟(无重复请求头开销);3. 核心场景:聊天软件、实时数据推送(如股票行情、直播弹幕)
  • 前后端数据交互 → 用 HTTP
  • 实时聊天 / 行情推送 → 用 WebSocket
  • 服务器大文件同步 → 用 FTP
  • 邮件发送功能 → 用 SMTP
UDP

“无连接、不可靠传输”(不保证数据到达,也不保证顺序),但 “低延迟、开销小” 适合对实时性要求远超可靠性的场景

应用层协议核心用途为什么选 UDP?
DNS域名解析(比如把 www.baidu.com 转成 IP)1. 解析请求 / 响应数据量极小(几十字节),就算丢包,客户端重试一次成本极低;2. 实时性要求高(打开网页前必须先解析域名,延迟要低)

执行流程

EventLoop 监听 Channel 上的 I/O 事件(如数据可读、连接建立)

一旦事件触发,就会调度该 Channel 绑定的 Pipeline

按顺序执行链中的 Handler 处理事件 / 数据

核心组件

Channel

网络通信的 “通道”,封装了底层 Socket,是数据读写的载体

(比如 NioSocketChannel 对应 TCP 客户端通道,NioServerSocketChannel 对应 TCP 服务端通道)

EventLoop与EventLoopGroup

EventLoop:“事件循环线程”,是 Netty 的核心调度器,负责监听 Channel 上的 I/O 事件

(如连接建立、数据可读、数据可写),并调用对应的 Handler 处理

一个EventLoop可管理多个Channel,每个Channel都有一个EventLoop(1:n)

一个EventLoop绑定一个线程,保证线程安全(1:1)

EventLoopGroup:EventLoop池

分两组(主从 Reactor 模型):

  • BossGroup(主线程组):负责接收客户端连接,不处理业务
  • WorkerGroup(从线程组):负责处理已连接 Channel 的 I/O 事件
ServerBootStrap与BootStrap

引导类

对应用程序进行配置并使应用程序运行起来

BootStrap:

客户端的引导类,调用bing()连接UDP,调用connect()连接TCP时创建一个单独的channel

服务端的 “启动助手”,用于配置服务端核心参数(线程组、Channel 类型、Pipeline、端口等),简化启动流程

ServerBootStrap:

服务端的引导类,调用bing()创建一个ServerChannel管理多个子Channel用于同客户端之间的通信

客户端的 “启动助手”,功能和 ServerBootstrap 类似,差异是客户端无需绑定端口,只需配置连接服务端的参数

ChannelHandler与ChannelPipeline

ChannelHandler:处理器

业务处理的 “逻辑单元”,分入站(处理读事件)和出站(处理写事件),是实际处理数据 / 事件的代码载体

ChannelPipeline:“处理器链”,是 Handler 的容器,按顺序存储多个 Handler(分为 ChannelInboundHandler 入站处理器、ChannelOutboundHandler 出站处理器)。数据读写时会按顺序经过 Pipeline 中的 Handler,实现 “分层处理”(如解码、业务逻辑、编码)

ChannelFuture

异步操作的 “结果占位符”,Netty 所有 I/O 操作(绑定、连接、读写)都是异步的,用它获取操作结果或添加回调

http://www.dtcms.com/a/582748.html

相关文章:

  • 我公司让别人做网站了怎么办个人微信公共号可以做微网站么
  • 做网站 发现对方传销兴义 网站建设
  • 节点小宝免费版流量机制解析:点对点直连技术与备用流量设计
  • 扁平化网站源码企业网站的建立费用 作什么科目
  • 卖货网站平台互联网o2o是什么意思
  • 网站建设需要通过哪些审批大同住房和城乡和建设网站
  • 做个企业网站要多少钱网络的推广
  • 一套随访系统源码,医院随访管理系统源码,三级随访平台源码,技术框架:Java+Spring boot,Vue,Ant-Design+MySQL5
  • 响应式网站开发现状宁波高端网站建设推广
  • 摄影网站网页设计网络营销的特征包括
  • 潍坊模板建站定制网站优惠做网站
  • 共筑网络安全,守护绿色家园
  • 一枚指纹,开启工业IoT设备安全与权限分级实践
  • 设计电子商务网站建设方案住建房官网查询
  • 响应式网站做mip小程序什么样才能移到微信上
  • GIS-gdal-java.lang.NoSuchMethodError
  • 注册安全工程师考试科目南京seo顾问
  • 省品牌建设联合会网站关键词查询
  • PsSuspend(7.23):无损挂起与恢复指定进程——精准“冻住”故障现场
  • 台州网站设计公司网站推广公司官网
  • 【LLaVA-NeXT】请问,为什么“Stderr显示是N/A”的信息呢
  • 二级域名做网站好不好2024房地产彻底结束
  • 网站建设动态页面修改删除广州网站优化地址
  • “十五五规划”智慧养老新图景:科技如何让晚年更温暖
  • 好看云在线网站模板下载 迅雷下载 迅雷下载地址花都网络推广seo公司
  • C语言--static与extern关键字
  • 科迪兔网站建设中国室内设计网站
  • 成都高标建设有限公司官方网站相亲网站透露自己做理财的女生
  • 安全与认证体系
  • 网站配色教程禁用wordpress编辑器