`

Netty IO线程模型学习总结

 
阅读更多

Netty框架的 主要线程是IO线程,线程模型的好坏直接决定了系统的吞吐量、并发性和安全性。

Netty的线程模型遵循了Reactor的基础线程模型。下面我们先一起看下该模型

Reactor线程模型

Reactor 单线程模型

screenshot

单线程模型中所有的IO操作都在一个NIO线程上操作:

包含接受客户端的请求,读取客户端的消息和应答。由于使用的是异步非阻塞的IO,所有的IO操作不会阻塞,理论上一个线程就可以处理所有的IO操作。

单线程模型适用小容量的应用。因为在高并发应用 可导致以下问题

  1. 一个线程同时处理成百上千的链路,性能上无法支撑。即使IO线程cpu 100%也无法满足要求。

  2. 当NIO线层负载过重,处理速度将变慢,会导致大量的客户端超时,重发,会更加重NIO的负载,最终导致系统大量超时

  3. 一旦IO线程跑飞,会导致整个系统通讯模块不可用,造成节点故障

Reactor多线程模型

screenshot

该模型组织了 一组线程进行IO的操作
特点:
1. 有专门的NIO线程---acceptor线程用于监听服务器,接受客户端的TCP请求
2. 网络操作的读写 由一个IO线程池负责 负责消息的读取 接收 编码和发送
3. 一个IO线程可以同时处理N条链路,但是一条链路 只对应一个Io线程。防止并发的操作问题

适合绝大多数场景,但是对于并发百万或者服务器需要对客户端握手进行安全认证,认证非常耗性能的情况,会导致性能瓶颈!

主次Reactor多线程模型

screenshot

接受客户端的连接 不在是一个单独的IO线程,而是一个Nio线程池:

Acceptor接受客户端的请求并处理完成后,将新建的socketChannel注册到IO线程池的某个线程上,由

他负责IO的读写 接编码工作。Acceptor线程池仅仅负责客户端的登录 握手 和 安全认证,一旦链路成

功,将链路注册到后端的线程池的线程上,有他进行后续的Io操作。

Netty线程模型


public void bind(int port) throws Exception {
// 配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
// 绑定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel arg0) throws Exception {
arg0.pipeline().addLast(new TimeServerHandler());
}
}

netty服务器在启动的时候,创建了两个NIOEventLoopGroup 独立的Reator线程池,一个用于接收客户端的TCP连接,一个用于处理IO的相关的读写操作。

Netty线程模型就是在reactor模型的基础上建立的,线程模型并不是一成不变的,通过启动参数的配置,可以在三种中切换。

启动过程,bossGroup 会选择一个EventLoop 需要绑定serverSocketChannel 进行接收客户端连接;处理后,将准备好的socketchnanell顺利注册到workGroup下。

netty服务端的创建过程

时序图:
screenshot

Netty 屏蔽NIO通信的底层细节:

  1. 首先创建ServerBootstrap,他是Netty服务端的启动辅助类

  2. 设置并绑定Reactor线程池。Netty的Reactor线程池是EventLoopGroup,它实际就是EventLoop线 程的数组。EventLoop的职责是处理所有注册到本线程多路复用器Selector上的Channel

  3. 设置NIOserverSocketChannel. Netty通过工厂类,利用反射创建NioServerSocketChannel对象

  4. 设置TCP参数

  5. 链路建立的时候创建并初始化ChannelPipeline.它本质就是一个负责处理网络事件的职责链,负责管理和执行ChannelHandler。网络事件以事件流的形式在ChannelPipeline中流转,由ChannelPipeline根据ChannelHandler的执行策略调度ChannelHandler的执行

    1. 绑定并启动监听端口
    2. 绑定端口,并启动。将会启动NioEventLoop负责调度和执行Selector轮询操作,选择准备就绪的Channel集合。当轮询到准备就绪的Channel之后,就由Reactor线程NioEventLoop执行ChannelPipeline的相应方法,最终调度并执行ChannelHandler。

NioEventLoop IO线程浅析

做为Netty的Reactor线程,因为要处理网络IO读写,所以聚合一个多路复用器对象,它通过open获取一个多路复用器。他的操作主要是在run方法的for循环中执行的。

  1. 做为bossGroup的线程 他需要绑定NioServerSocketChannel 来监听客户端的connet请求,并处理连接和校验。
  2. 作为workGroup线层组的线程,需要将连接就绪的SocketChannel绑定到线程中,所以一个客户端连接至对应一个线程,一个线程可以绑定多个客户端连接。

从调度层面看,也不存在在EventLoop线程中 再启动其它类型的线程用于异步执行其它的任务,这样就避免了多线程并发操作和锁竞争,提升了I/O线程的处理和调度性能。

NioEventLoop线程保护

IO操作是线程是的核心,一旦出现故障,导致其上面的多路复用器和多个链路无法正常工作,因此他需要特别的保护。他在以下两个方面做了保护处理:

  1. 谨慎处理异常

异常可能导致线程跑飞,会导致线程下的所有链路不可用,这时采try{}catch(Throwable) 捕获异常,防止跑飞。出现异常后,可以恢复执行。netty的原则是 某个消息的异常不会导致整个链路的不可用,某个链路的不可用,不能导致其他链路的不可用。

  1. 规避NIO BUG

screenshot

Selector.select 没有任务执行时,可能触发JDK的epoll BUG。这就是著名的JDK epoll BUG,JDK1.7早期版本 号称解决了,但是据网上反馈,还有此BUG。服务器直接表现为 IO线程的 CPU很高,可能达到100%,可能会导致节点故障!!!

为什么会发生epoll Bug

screenshot

Netty的修复策略为:

  1. 对Selector的select的操作周期进行统计

  2. 对每完成一次空的select操作进行一次计数

  3. 在某周期内(如100ms)连续N此空轮询, 说明触发了epoll死循环BUG

  4. 检测到死循环后,重建selector的方式让系统恢复正常

netty采用此策略,完美避免了此BUG的发生。

netty刚刚入门,希望能和大家一起交流。后面也会学习下netty在notify中的应用。

分享到:
评论

相关推荐

    简单了解Java Netty Reactor三种线程模型

    Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接; 2)作为NIO客户端,向服务端发起TCP连接; 3)读取通信对端的请求或者应答消息;...

    深入理解Netty线程模型

    从这篇文章中,大家可以学习到如下知识:什么是I/O多路复用Reactor三种线程模型Netty线程模型NioEventLoop源码分析JDKepollbug学习I/O多路复用之前,我们先来了解如下几个概念:阻塞I/O:客户端从socket中读取数据或...

    Netty初探:掌握高性能网络通信框架,提升Java网络编程技能

    Netty的线程模型,将IO操作和业务逻辑清晰地分离,使开发者可以专注于业务逻辑的开发。此外,Netty还提供了丰富的组件和工具,如Bootstrap、Channel、Selector、NioEventLoop等,让网络编程更加简单和高效。通过学习...

    java多线程tcpsocketserver源码-netty-learning:网络学习

    高度可定制的线程模型 表现 高吞吐量,低延迟 更少的资源消耗 最小化内存拷贝 安全SSL/TLS 支持 建筑学 核 事件模型 通用通信 API 支持零复制的富字节缓冲区 io.netty.buffer, io.netty.common, io.netty.resolver, ...

    Netty4.1.101稳定版本

    Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。  简单地说Netty封装了JDK的NIO,不用再写一大堆复杂...对Selector做了很多细小的优化,reactor线程模型能做到高效的并发处理。

    精通并发与netty视频教程(2018)视频教程

    72_Netty线程模型深度解读与架构设计原则 73_Netty底层架构系统总结与应用实践 74_Netty对于异步读写操作的架构思想与观察者模式的重要应用 75_适配器模式与模板方法模式在入站处理器中的应用 76_Netty项目开发过程...

    Netty高性能网络应用框架.rar

    在学习Netty之前,我们需要对IO模型要有一定的了解,其中最重要的就是NIO,所以今天打算先对NIO进行一些简单的梳理。 IO模型 常见IO模型分为几种: BIO :Blocking IO, 即同步阻塞式IO。Client和Server的每建立一次...

    精通并发与netty 无加密视频

    第72讲:Netty线程模型深度解读与架构设计原则 第73讲:Netty底层架构系统总结与应用实践 第74讲:Netty对于异步读写操作的架构思想与观察者模式的重要应用 第75讲:适配器模式与模板方法模式在入站处理器中的...

    NIO框架Netty实现高性能高并发

    Java异步NIO框架Netty实现高性能高...心的设计Reactor线程模型,达到上述性能指标是完全有可能的。 下面我们就一起来看下Netty是如何支持10W TPS的跨节点远程服务调用的,在正式开始讲解之前,我们先简单介绍下Netty。

    高清Netty5.0架构剖析和源码解读

    Linux 的网络IO模型简介4 1.1.3. IO复用技术介绍7 1.1.4. JAVA的异步IO8 1.1.5. 业界主流的NIO框架介绍10 2.NIO入门10 2.1. NIO服务端10 2.2. NIO客户端13 3.Netty源码分析16 3.1. 服务端创建16 3.1.1. 服务端启动...

    JAVA版基于netty的物联网高并发智能网关.rar

    java 1.4起,jdk支持了NIO(NEW IO),因NIO(os nonblocking)的非阻塞式工作方式,让应用服务器可以极大的优化线程模型,相比传统的阻塞式IO线程和链路一对一的模式,NIO只需少量的线程即可处理所有的链路,这对广大的...

    netty面试专题-答案-一起学习

    1.BIO、NIO 和 AIO 的区别? BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。...基于 Reactor 线程模型。 在 Reactor 模式中,事件分发器等待某个事件或者可应用或个操作的状态发

    基于javatcpsocket通信的拆包和装包源码-Netty-practice:Netty学习实践

    Netty学习实践 源码分析 BIO/NIO/AIO基础 阻塞I/O 非阻塞I/O I/O复用 信号驱动的I/O 异步I/O Java I/O模型 同步阻塞IO 1:1同步阻塞IO通信模型 M:N形式的同步阻塞IO通信模型 非阻塞式IO模型(NIO) NIO+单线程Reactor...

    精通并发与 netty 视频教程(2018)视频教程

    Channel选择器工厂与轮询算法及注册底层实现 72_Netty线程模型深度解读与架构设计原则 73_Netty底层架构系统总结与应用实践 74_Netty对于异步读写操作的架构思想与观察者模式的重要应用 75_适配器模式与模板方法模式...

    ieda+netty.zip

    这就是书本上说的总体来看,与阻塞 I/O 模型相比,这种模型提供了更好的资源管理: 1.使用较少的线程便可以处理许多连接,因此也减少了内存管理和上下文切换所带来开销; 2.当没有 I/O 操作需要处理的时候,线程也...

    leetcode题库-Blog:Fashion'sBlog个人学习笔记,涵盖JVM、数据结构、算法、设计模式、中间件、数据库、缓存、分布式微服

    全手写急速理解Netty模型及IO模型应用实战 Netty之IO模型开发本质手写部分实现推导篇 全手写基于Netty的RPC框架自定义协议,连接池 全手写基于Netty的RPC框架 协议编解码问题 粘包拆包与内核关系 ... Elasticsearch ...

    Netty实现高性能的五个因素.pptx

    此文档着重分析了Netty实现高并发的五个重要因素,包含了网络IO,零拷贝,内存池管理,高效的Reactor多线程模型,无锁化串行设计几个方面。

    基于javatcpsocket通信的拆包和装包源码-NettyTree:网状树

     1)单线程模型,所有的IO操作都在一个NIO线程上完成   存在性能和可靠性上的问题  2)多线程模型,有一组NIO线程处理IO操作   有一个专门的NIO线程-Acceptor线程用于监听服务端,接收客户端的TCP连接请求;   ...

    基于Netty和Python的face-recognition库实现的高性能的人脸识别服务器.完整项目代码 计算机毕设

    因为本人的技术栈是Java,所以使用Java的高性能网络IO模型库Netty进行服务器的开发,AI的模型大部分都是Python进行开发的,所以也使用了基于Python的人脸识别框架face_recoginize用来开发人脸识别的微服务。...

    netty-study:netty-study

    IO模型 生物 蔚来 通信 面向流(乡村公路) 面向缓冲(高速公路,多路替代技术) 处理 双向IO(多线程) 非双层IO(React堆Reactor) 触发 无 选择器(选择性机制) 1.3 IO的操作汇总 IO(BIO)同步双向IO NIO异步...

Global site tag (gtag.js) - Google Analytics