iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Tomcat中NIO模型的示例分析
  • 571
分享到

Tomcat中NIO模型的示例分析

2023-06-02 14:06:33 571人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关Tomcat中NIO模型的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、I/O复用模型解读Tomcat的Nio是基于I/O复用来实现的。对这点一定要清楚,不然我们的讨论就不在

这篇文章给大家分享的是有关TomcatNIO模型的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一、I/O复用模型解读

Tomcat的Nio是基于I/O复用来实现的。对这点一定要清楚,不然我们的讨论就不在一个逻辑线上。下面这张图学习过I/O模型知识的一般都见过,出自《UNIX网络编程》,I/O模型一共有阻塞式I/O,非阻塞式I/O,I/O复用(select/poll/epoll),信号驱动式I/O和异步I/O。这篇文章讲的是I/O复用。

Tomcat中NIO模型的示例分析

IO复用.png

这里先来说下用户态和内核态,直白来讲,如果线程执行的是用户代码,当前线程处在用户态,如果线程执行的是内核里面的代码,当前线程处在内核态。更深层来讲,操作系统为代码所处的特权级别分了4个级别。

不过现代操作系统只用到了0和3两个级别。0和3的切换就是用户态和内核态的切换。更详细的可参照《深入理解计算机操作系统》。I/O复用模型,是同步非阻塞,这里的非阻塞是指I/O读写,对应的是recvfrom操作,因为数据报文已经准备好,无需阻塞。

说它是同步,是因为,这个执行是在一个线程里面执行的。有时候,还会说它又是阻塞的,实际上是指阻塞在select上面,必须等到读就绪、写就绪等网络事件。有时候我们又说I/O复用是多路复用,这里的多路是指N个连接,每一个连接对应一个channel,或者说多路就是多个channel。

复用,是指多个连接复用了一个线程或者少量线程(在Tomcat中是Math.min(2,Runtime.getRuntime().availableProcessors()))。

上面提到的网络事件有连接就绪,接收就绪,读就绪,写就绪四个网络事件。I/O复用主要是通过Selector复用器来实现的,可以结合下面这个图理解上面的叙述。

Tomcat中NIO模型的示例分析

Selector图解.png

二、TOMCAT对IO模型的支持

Tomcat中NIO模型的示例分析

tomcat支持IO类型图.png

tomcat从6以后开始支持NIO模型,实现是基于jdk的java.nio包。这里可以看到对read body 和response body是Blocking的。关于这点在第6.3节源代码阅读有重点介绍。

三、TOMCAT中NIO的配置与使用

在Connector节点配置protocol=”org.apache.coyote.Http11.Http11NioProtocol”,Http11NioProtocol协议下默认最大连接数是10000,也可以重新修改maxConnections的值,同时我们可以设置最大线程数maxThreads,这里设置的最大线程数就是Excutor的线程池的大小。

在BIO模式下实际上是没有maxConnections,即使配置也不会生效,BIO模式下的maxConnections是保持跟maxThreads大小一致,因为它是一请求一线程模式。

四、NioEndpoint组件关系图解读

Tomcat中NIO模型的示例分析

tomcatnio组成.png

我们要理解tomcat的nio最主要就是对NioEndpoint的理解。它一共包含LimitLatch、Acceptor、Poller、SocketProcessor、Excutor5个部分。

LimitLatch是连接控制器,它负责维护连接数的计算,nio模式下默认是10000,达到这个阈值后,就会拒绝连接请求。Acceptor负责接收连接,默认是1个线程来执行,将请求的事件注册到事件列表。

有Poller来负责轮询,Poller线程数量是cpu的核数Math.min(2,Runtime.getRuntime().availableProcessors())。由Poller将就绪的事件生成SocketProcessor同时交给Excutor去执行。Excutor线程池的大小就是我们在Connector节点配置的maxThreads的值。

在Excutor的线程中,会完成从socket中读取http request,解析成httpservletRequest对象,分派到相应的servlet并完成逻辑,然后将response通过socket发回client。

在从socket中读数据和往socket中写数据的过程,并没有像典型的非阻塞的NIO的那样,注册OP_READ或OP_WRITE事件到主Selector,而是直接通过socket完成读写,这时是阻塞完成的,但是在timeout控制上,使用了NIO的Selector机制,但是这个Selector并不是Poller线程维护的主Selector,而是BlockPoller线程中维护的Selector,称之为辅Selector。详细源代码可以参照 第6.3节。

五、NioEndpoint执行序列图

Tomcat中NIO模型的示例分析

tomcatnio序列图.png

在下一小节NioEndpoint源码解读中我们将对步骤1-步骤11依次找到对应的代码来说明。

六、NioEndpoint源码解读

1、初始化

无论是BIO还是NIO,开始都会初始化连接限制,不可能无限增大,NIO模式下默认是10000。

Tomcat中NIO模型的示例分析

6.2、步骤解读

下面我们着重叙述跟NIO相关的流程,共分为11个步骤,分别对应上面序列图中的步骤。

步骤1:绑定IP地址及端口,将ServerSocketChannel设置为阻塞。

这里为什么要设置成阻塞呢,我们一直都在说非阻塞。Tomcat的设计初衷主要是为了操作方便。这样这里就跟BIO模式下一样了。只不过在BIO下这里返回的是

Socket,NIO下这里返回的是SocketChannel。

Tomcat中NIO模型的示例分析

步骤2:启动接收线程

Tomcat中NIO模型的示例分析

步骤3:ServerSocketChannel.accept()接收新连接

Tomcat中NIO模型的示例分析

步骤4:将接收到的链接通道设置为非阻塞

步骤5:构造Niochannel对象

步骤6:reGISter注册到轮询线程

Tomcat中NIO模型的示例分析

步骤7:构造PollerEvent,并添加到事件队列

Tomcat中NIO模型的示例分析

步骤8:启动轮询线程

Tomcat中NIO模型的示例分析

步骤9:取出队列中新增的PollerEvent并注册到Selector

Tomcat中NIO模型的示例分析

步骤10:Selector.select()

Tomcat中NIO模型的示例分析

Tomcat中NIO模型的示例分析

步骤11:根据选择的SelectionKey构造SocketProcessor提交到请求处理线程

Tomcat中NIO模型的示例分析

6.3、NioBlockingSelector和BlockPoller介绍

上面的序列图有个地方我没有描述,就是NiOSelectorPool这个内部类,是因为在整体理解tomcat的nio上面在序列图里面不包括它更好理解。

在有了上面的基础后,我们在来说下NioSelectorPool这个类,对更深层了解Tomcat的NIO一定要知道它的作用。NioEndpoint对象中维护了一个NioSelecPool对象,这个NioSelectorPool中又维护了一个BlockPoller线程,这个线程就是基于辅Selector进行NIO的逻辑。

以执行servlet后,得到response,往socket中写数据为例,最终写的过程调用NioBlockingSelector的write方法。代码如下:

Tomcat中NIO模型的示例分析

Tomcat中NIO模型的示例分析

也就是说当socket.write()返回0时,说明网络状态不稳定,这时将socket注册OP_WRITE事件到辅Selector,由BlockPoller线程不断轮询这个辅Selector,直到发现这个socket的写状态恢复了,通过那个倒数计数器,通知Worker线程继续写socket动作。看一下BlockSelector线程的代码逻辑:

Tomcat中NIO模型的示例分析

使用这个辅Selector主要是减少线程间的切换,同时还可减轻主Selector的负担。

七、关于性能

下面这份报告是我们压测的一个结果,跟想象的是不是不太一样?几乎没有差别,实际上NIO优化的是I/O的读写,如果瓶颈不在这里的话,比如传输字节数很小的情况下,BIO和NIO实际上是没有差别的。

NIO的优势更在于用少量的线程hold住大量的连接。还有一点,我们在压测的过程中,遇到在NIO模式下刚开始的一小段时间内容,会有错误,这是因为一般的压测工具是基于一种长连接,也就是说比如模拟1000并发,那么同时建立1000个连接,下一时刻再发送请求就是基于先前的这1000个连接来发送,还有TOMCAT的NIO处理是有POLLER线程来接管的,它的线程数一般等于CPU的核数,如果一瞬间有大量并发过来,POLLER也会顿时处理不过来。

Tomcat中NIO模型的示例分析

压测1.jpeg

Tomcat中NIO模型的示例分析

压测2.jpeg

感谢各位的阅读!关于“Tomcat中NIO模型的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Tomcat中NIO模型的示例分析

本文链接: https://www.lsjlt.com/news/230323.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Tomcat中NIO模型的示例分析
    这篇文章给大家分享的是有关Tomcat中NIO模型的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、I/O复用模型解读Tomcat的NIO是基于I/O复用来实现的。对这点一定要清楚,不然我们的讨论就不在...
    99+
    2023-06-02
  • Java中NIO的示例分析
    这篇文章主要介绍了Java中NIO的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Java思维导图二、I/O模型I/O模型的本质是用什么样的通道进行数据的发送和接...
    99+
    2023-06-29
  • HTML中盒模型的示例分析
    小编给大家分享一下HTML中盒模型的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!盒模型规定了元素框处理元素内容width与height值、内边距padding、边框border 和 外边距margin 的数值大小...
    99+
    2023-06-08
  • Android之从IO到NIO的模型机制实例分析
    这篇文章主要讲解了“Android之从IO到NIO的模型机制实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android之从IO到NIO的模型机制实例分析”吧!1 Basic IO模...
    99+
    2023-07-05
  • PHP中原型模式的示例分析
    这篇文章将为大家详细讲解有关PHP中原型模式的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。原型模式其实更形象的来说应该叫克隆模式。它主要的行为是对对象进行克隆,但是又把被克隆的对象称之为最初的原...
    99+
    2023-06-20
  • CSS中盒子模型的示例分析
    这篇文章主要为大家展示了“CSS中盒子模型的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CSS中盒子模型的示例分析”这篇文章吧。 所有HTML元素可...
    99+
    2024-04-02
  • kubernetes中网络模型的示例分析
    这篇文章主要介绍kubernetes中网络模型的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Kubernetes从Docker默认的网络模型中独立出来形成一套自己的网络模型。模型的基础原则是:每个Pod都拥...
    99+
    2023-06-04
  • css盒模型的示例分析
    小编给大家分享一下css盒模型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 1.各种盒模型 inline-blo...
    99+
    2024-04-02
  • Node.js中多进程模型的示例分析
    这篇文章将为大家详细讲解有关Node.js中多进程模型的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Cluster 模块Node.js 提供了 Cluster ...
    99+
    2024-04-02
  • jvm中java内存模型的示例分析
    这篇文章主要介绍了jvm中java内存模型的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、java内存模型和java内存结构有什么区别 1、java内存...
    99+
    2023-06-19
  • CSS中盒模型用法的示例分析
    CSS中盒模型用法的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。视觉类型的媒体根据CSS的视觉格式化模型(Visual format...
    99+
    2024-04-02
  • db2进程模型的示例分析
    这期内容当中小编将会给大家带来有关db2进程模型的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。DB2 进程技术模型 所有 DB2 数据库服务器使用的进程技术...
    99+
    2024-04-02
  • RBAC权限模型的示例分析
    小编给大家分享一下RBAC权限模型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!权限系统与RBAC模型概述RBAC(R...
    99+
    2024-04-02
  • Java内存模型的示例分析
    这篇文章主要为大家展示了“Java内存模型的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java内存模型的示例分析”这篇文章吧。1. 为什么要有内存模型?要想回答这个问题,我们需要先弄...
    99+
    2023-06-29
  • Java原型模式的示例分析
    这篇文章主要介绍了Java原型模式的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.思考问题现在有一只羊 tom,姓名为: tom,年龄为:1,颜色为:白色,请编写...
    99+
    2023-06-29
  • Python中Unet语义分割模型的示例分析
    小编给大家分享一下Python中Unet语义分割模型的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是语义分割语义分割任务,如下图所示:简而言之,...
    99+
    2023-06-22
  • Netty、MINA、Twisted中线程模型的示例分析
    这篇文章主要介绍了Netty、MINA、Twisted中线程模型的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。要想开发一个高性能的TCP服务器,熟悉所使用框架的线程...
    99+
    2023-06-04
  • 深入浅析Java NIO中的IO模型
    这期内容当中小编将会给大家带来有关深入浅析Java NIO中的IO模型,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一.什么是同步?什么是异步  同步和异步的概念出来已经很久了,网上有关同步和异步的说法也...
    99+
    2023-05-31
    java io模型 nio
  • JavaScript设计模型Iterator的示例分析
    这篇文章给大家分享的是有关JavaScript设计模型Iterator的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Iterator Pattern是一个很重要也很简单...
    99+
    2024-04-02
  • Java网络编程与NIO详解11:Tomcat中的Connector源码分析(NIO)
    本文转载 https://www.javadoop.com本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tutorial喜欢的话麻烦点...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作