`
uule
  • 浏览: 6358018 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

【一个故事讲清楚NIO+Netty线程模型】

 
阅读更多

五种网络io模型

一个简单故事讲述NIO

 

blocking I/O    阻塞 

nonblocking I/O  非阻塞

I/O multiplexing (select and poll)  多路复用

signal driven I/O (SIGIO)   信号驱动

asynchronous I/O (the POSIX aio_functions)  异步

 

 

例子:

假设某银行只有10个职员。该银行的业务流程分为以下4个步骤:

 

1) 顾客填申请表(5分钟);

2) 职员审核(1分钟);

3) 职员叫保安去金库取钱(3分钟);

4) 职员打印票据,并将钱和票据返回给顾客(1分钟)。

 

  我们看看银行不同的工作方式对其工作效率到底有何影响。

 

 

1、 BIO方式

  每来一个顾客,马上由一位职员来接待处理,并且这个职员需要负责以上4个完整流程。当超过10个顾客时,剩余的顾客需要排队等候。

  我们算算这个银行一个小时到底能处理多少顾客?一个职员处理一个顾客需要10分钟(5+1+3+1)时间,一个小时(60分钟)能处理6个顾客,一共10个职员,那就是只能处理60个顾客。

  可以看到银行职员的工作状态并不饱和,比如在第1步,其实是处于等待中。

 

  这种工作其实就是BIO,每次来一个请求(顾客),就分配到线程池中由一个线程(职员)处理如果超出了线程池的最大上限(10个),就扔到队列等待 。

 

 

2 、NIO方式

  如何提高银行的吞吐量呢?

 

  思路:分而治之,将任务拆分开来,由专门的人负责专门的任务。

 

  具体来讲,银行专门指派一名职员A,A的工作就是每当有顾客到银行,他就递上表格让顾客填写,每当有顾客填好表后,A就将其随机指派给剩余的9名职员完成后续步骤。

  我们计算下这种工作方式下银行一个小时到底能处理多少顾客?

  假设顾客非常多,职员A的工作处于饱和中,他不断的将填好表的顾客带到柜台处理,柜台一个职员5分钟能处理完一个顾客,一个小时9名职员能处理:9*(60/5)=108。

  可见工作方式的转变能带来效率的极大提升。

 

      这种工作方式其实就NIO的思路。下图是非常经典的NIO说明图,mainReactor线程负责监听server socket,accept新连接,并将建立的socket分派给subReactor;subReactor可以是一个线程,也可以是线程池(一般可以设置为CPU核数),负责多路分离已连接的socket,读写网络数据,这里的读写网络数据可类比顾客填表这一耗时动作,具体的业务处理功能,其扔给worker线程池完成

 

  可以看到典型NIO有三类线程,分别是mainReactor线程、subReactor线程、work线程。不同的线程干专业的事情,最终每个线程都没空着,系统的吞吐量自然就上去了。



 上面这幅图描述了netty的线程模型,其中mainReacotor,subReactor,Thread Pool是三个线程池。mainReactor负责处理客户端的连接请求,并将accept的连接注册到subReactor的其中一个线程上;subReactor负责处理客户端通道上的数据读写;Thread Pool是具体的业务逻辑线程池,处理具体业务。

 

netty默认模式

在默认情况下,netty的线程池有下面的两条规则:

(1).mainReactor和subReator可由用户指定。

(2).Thread Pool业务逻辑线程池可以使用SubReactor线程池。

注意:

(1).用户可以将mainReactor和subReator指定为同一个线程池,但不建议这样做因为TCP连接的三次握手I/O频繁,使用一个独立的mainReactor线程池可以提升性能

(2).如果业务逻辑中有大量耗费时间的操作,比如数据库读写等,这时有必要显示指定Thread Pool业务逻辑线程池从而让subReactor线程池可以及时处理其他客户端的请求

        

3、 异步方式

  第二种工作方式有没有什么可以提高的地方呢?

 

  仔细查看可发现第3步骤这3分钟柜台职员是在等待中度过的,那怎么能让柜台职员保持满负荷呢?

 

  还是分而治之的思路,指派1个职员B来专门负责第3步骤。每当柜台员工完成第2步时,就通知职员B来负责与保安沟通取钱。这时候柜台员工可以继续处理下一个顾客。当职员B拿到钱之后,他会怎么办呢?他会通知顾客钱已经到柜台了,让顾客重新排队处理,当柜台职员再次服务该顾客时,发现该顾客前3步已经完成,直接执行第4步即可。

 

  我们可以算算通过这种方法,银行的吞吐量能提高到多少。

 

  假设职员B的工作非常饱和,柜台一个职员现在2分钟能处理完一个顾客,一个小时8名职员能处理:8*(60/2)=240。

 

  在当今web服务中,经常需要通过RPC或者Http等方式调用第三方服务,这里对应的就是第3步,如果这步耗时较长,通过异步方式将能极大降低资源使用率。

 

  jetty Continuations 就实现了上述异步方式,有兴趣的同学可以去尝试下(http://wiki.eclipse.org/Jetty/Feature/Continuations)。

 

  NIO+异步的方式能让少量的线程(资源)做大量的事情,这适用于很多应用场景,比如代理服务、api服务、长连接服务等等,这些应用如果用同步方式将耗费大量机器资源。尽管NIO+异步能提高系统吞吐量,但其并不能让一个请求的等待时间下降,相反可能会增加等待时间。

 

 4 小结

  总结就一句:“分而治之,将任务拆分开来,由专门的人负责专门的任务”,这不仅在计算机领域生效,在整个社会领域都生效。

  • 大小: 80.5 KB
分享到:
评论

相关推荐

    NIO+Netty5视频教程与Netty源码剖析视频教程

    《NIO+Netty5视频教程与Netty源码剖析视频教程》是一份全面解析网络编程框架Netty的教育资源,旨在帮助学习者深入理解和应用NIO(非阻塞I/O)以及Netty5的核心技术。该教程分为两个主要部分,分别针对理论分析和实战...

    【项目实战】Netty源码剖析&NIO;+Netty5各种RPC架构实战演练三部曲视频教程(未加密)

    - **EventLoopGroup**:管理多个EventLoop实例,每个EventLoop都是一个线程,负责处理分配给它的Channel上的所有I/O操作。 - **Handler**:实现ChannelInboundHandler或ChannelOutboundHandler接口,处理读写事件。 ...

    NIO+Netty5视频教程2018

    【标题】"NIO+Netty5视频教程2018"揭示了两个核心主题:Netty框架的源码分析和基于NIO的RPC架构实战。这个教程旨在帮助Java开发者深入理解和应用NIO(Non-blocking Input/Output)技术以及Netty网络框架,尤其在构建...

    深入Hotspot源码与Linux内核理解NIO与Netty线程模型.rar

    《深入Hotspot源码与Linux内核理解NIO与Netty线程模型》这份资料主要探讨了Java的Hotspot虚拟机源码、Linux内核、非阻塞I/O(NIO)以及Netty框架的线程模型。这些知识点在构建高性能、高并发的网络应用中至关重要。 ...

    nio+bio+netty+fx.zip

    项目中的`nio+bio+netty+fx`可能包含以下文件: - `BioChatServer.java`: 实现基于BIO的服务器端代码。 - `BioChatClient.java`: 实现基于BIO的客户端代码。 - `NioChatServer.java`: 实现基于NIO的服务器端代码。 -...

    springboot+netty+websocket+redis

    **SpringBoot+Netty+WebSocket+Redis:构建分布式实时聊天应用** 在当今的互联网世界中,实时通信和数据共享是许多应用程序的核心需求。Spring Boot作为一款流行的Java框架,因其简洁的配置和快速开发特性而备受...

    springboot+netty实现mqtt协议的broken

    标题"springboot+netty实现mqtt协议的broken"可能意味着这个项目旨在解决Spring Boot与Netty集成时可能出现的问题,或者是一个关于如何处理MQTT连接中断的教程。在实际应用中,MQTT连接可能会因为各种原因断开,例如...

    springboot2.3+modbusTcp协议+netty高性能物联网服务

    Netty NIO high performance高性能;Modbus Function sync/aync 同步/异步非阻塞;Modbus IoT Data Connector Supports工业物联网平台IoT支持。

    Spring Boot + Netty 实现温湿度采集的展示

    - **特性**:NIO基础、零拷贝、线程模型优化、高效缓冲区、丰富的协议支持、强大的编解码器等。 - **在项目中的角色**:Netty作为通信层,负责接收来自温湿度传感器的实时数据,这些数据可能是通过TCP或UDP等协议...

    Netty简介 Netty线程模型和EventLoop Codec编码与解码 ByteBuf容器

    EventLoop是Netty的核心组件,它是一个单线程执行任务的循环,负责处理I/O事件并分发到对应的处理器。每个EventLoop都包含一个Selector,用于监听多个通道的事件。通过多路复用技术,EventLoop可以高效地处理大量...

    java多线程程序设计:Java NIO+多线程实现聊天室

    java多线程程序设计:Java NIO+多线程实现聊天室 Java基于多线程和NIO实现聊天室 涉及到的技术点 线程池ThreadPoolExecutor 阻塞队列BlockingQueue,生产者消费者模式 Selector Channel ByteBuffer ProtoStuff 高...

    基于java开发的NIO+多线程实现聊天室+源码+项目解析(毕业设计&课程设计&项目开发)

    基于java开发的NIO+多线程实现聊天室+源码+项目解析,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 项目简介: 涉及到的技术点 线程池ThreadPoolExecutor 阻塞...

    从NIO到Netty,编程实战出租车905协议-08172347.pdf

    905.4-2014协议,是交通运输部公路科学研究院起草定制的一个协议标准,它也是基于TCP之上的一个应用层传输协议。 第2章,介绍在Socket编程过程中一些基础知识,让大家建立起对这块知识内容的一个整体轮廓; 第3章,...

    多线程精品资源--Java NIO+多线程实现聊天室.zip

    在这个“多线程精品资源--Java NIO+多线程实现聊天室”的压缩包中,我们可以推测它包含了一套关于如何使用Java NIO和多线程技术来创建一个实时聊天应用的教程或示例代码。 首先,多线程是Java中并行处理的基础。...

    05.Netty线程模型.rar

    Netty的线程模型基于NIO(非阻塞I/O)的概念,其核心组件包括BossGroup、WorkerGroup以及EventLoop。BossGroup负责接收新的连接请求,而WorkerGroup则处理已建立连接上的读写事件。这两个组都是由多个EventLoop组成...

    springboot+netty+mybatis+sqlserver

    标题 "springboot+netty+mybatis+sqlserver" 涉及到的是一个使用Spring Boot、Netty、MyBatis以及SQL Server构建的项目。这个项目可能是一个高性能、轻量级的网络通信应用,利用Spring Boot的便利性和Netty的高效...

    netty 线程模型

    这是一本详细介绍了netty线程模型的书籍,包括 nio核心

    spring boot +maven+ netty4+protostuff+zookeeper实现一个轻量级RPC框架

    Netty:它使 NIO 编程更加容易,屏蔽了 Java 底层的 NIO 细节。 Protostuff:它基于 Protobuf 序列化框架,面向 POJO,无需编写 .proto 文件。 ZooKeeper:提供服务注册与发现功能,开发分布式系统的必备选择,同时...

    Java-NIO-Netty框架学习

    Netty是基于Java NIO构建的一个高性能、异步事件驱动的网络应用框架,常用于开发网络服务器和客户端,如TCP、UDP协议的服务器和客户端,以及HTTP、FTP等高层协议的应用。 Netty的核心设计理念是减少系统开销,提高...

Global site tag (gtag.js) - Google Analytics