Tomcat 网络通信模型剖析(全)

1.      Tomcat 支持四种线程模型介绍

2.      Tomcat BIO、NIO实现过程源码解析

3.      Tomcat connector 并发参数解读

4.      Tomcat 类加载机制源码解析

一、Tomcat 支持四种线程模型介绍

什么是IO?

IO是指为数据传输所提供的输入输出流,其输入输出对象可以是:文件、网络服务、内存等。

 

 

 

 

什么是IO模型?

提问:

假设应用在从硬盘中读取一个大文件过程中,此时CPU会与硬盘一样出于高负荷状态么?

演示:

l  演示观察大文件的读写过程当中CPU 有没有发生大波动。

演示结果:CPU 没有太高的增涨

通常情况下IO操作是比较耗时的,所以为了高效的使用硬件,应用程序可以用一个专门线程进行IO操作,而另外一个线程则利用CPU的空闲去做其它计算。这种为提高应用执行效率而采用的IO操作方法即为IO模型。

 

各IO 简单说明:

IO模型

描述

BIO

 同步阻塞式IO,即Tomcat使用传统的java.io进行操作。该模式下每个请求都会创建一个线程,对性能开销大,不适合高并发场景。优点是稳定,适合连接数目小且固定架构。

NIO

同步非阻塞式IO,jdk1.4 之后实现的新IO。该模式基于多路复用选择器监测连接状态在同步通知线程处理,从而达到非阻塞的目的。比传统BIO能更好的支持并发性能。Tomcat 8.0之后默认采用该模式

APR

 全称是 Apache Portable Runtime/Apache可移植运行库),是Apache HTTP服务器的支持库。可以简单地理解为,Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作。使用需要编译安装APR 库

AIO

(asynchronous  I/O)

 异步非阻塞式IO,jdk1.7后之支持 。与nio不同在于不需要多路复用选择器,而是请求处理线程执行完程进行回调调知,已继续执行后续操作。Tomcat 8之后支持。

使用指定IO模型的配置方式:

配置 server.xml 文件当中的 <Connector  protocol="HTTP/1.1">   修改即可。

默认配置 8.0  protocol=“HTTP/1.1” 8.0 之前是 BIO 8.0 之后是NIO

BIO

protocol=“org.apache.coyote.http11.Http11Protocol“

NIO

protocol=”org.apache.coyote.http11.Http11NioProtocol“

AIO

protocol=”org.apache.coyote.http11.Http11Nio2Protocol“

APR

protocol=”org.apache.coyote.http11.Http11AprProtocol“

 

 

二、Tomcat BIO、NIO实现过程源码解析

提问:

BIO 与NIO有什么区别?

 

分别演示在高并发场景下BIO与NIO的线程数的变化?

演示数据:

 

每秒提交数

BIO执行线程

NIO执行线程

预测

200

200线程

20线程

实验实际

200

55 wait个线程

23个线程

模拟生产环境

200

229个run线程

20个wait 线程

1、网络

2、程序执行业务用时

 

结论:

 

BIO 线程模型讲解

 

 

 

 

 

NIO 线程模型讲解

 

 

 

 

BIO 源码解读

线程组:

Accept 线程组  acceptorThreadCount=

exec 线程组    maxThread

 

JIoEndpoint

Acceptor extends Runnable

SocketProcessor extends Runnable

 

BIO

 线程数量 会受到 客户端阻塞、网络延迟、业务处理慢===>线程数会更多

NIO

 线程数量 会受到业务处理慢===>线程数会更多

三、Tomcat connector 并发参数解读

名称

描述

acceptCount

等待最大队列

address

绑定客户端特定地址,127.0.0.1

bufferSize

每个请求的缓冲区大小。

bufferSize * maxThreads

compression

是否启用文档压缩

compressableMimeTypes

text/html,text/xml,text/plain

connectionTimeout

客户发起链接 到 服务端接收为止,中间最大的等待时间

connectionUploadTimeout

upload 情况下连接超时时间

disableUploadTimeout

true 则使用connectionTimeout

enableLookups

禁用DNS查询 true

keepAliveTimeout

当长链接闲置 指定时间主动关闭 链接 ,前提是客户端请求头 带上这个 head"connection" " keep-alive"

maxKeepAliveRequests

最大的 长连接数

maxHttpHeaderSize

 

maxSpareThreads

BIO 模式下 最多线闲置线程数

maxThreads(执行线程)

最大执行线程数

minSpareThreads(初始线业务线程 10)

BIO 模式下 最小线闲置线程数

 

四、Tomcat 类加载机制源码解析

类加载的本质

是用来加载 Class 的。它负责将 Class 的字节码形式转换成内存形式的 Class 对象。字节码可以来自于磁盘文件 *.class,也可以是 jar 包里的 *.class,也可以来自远程服务器提供的字节流,字节码的本质就是一个字节数组 []byte,它有特定的复杂的内部格式。

JVM 运行实例中会存在多个 ClassLoader,不同的 ClassLoader 会从不同的地方加载字节码文件。它可以从不同的文件目录加载,也可以从不同的 jar 文件中加载,也可以从网络上不同的静态文件服务器来下载字节码再加载。

jvm里ClassLoader的层次结构

 

类加载器层次结构.png

BootstrapClassLoader(启动类加载器)

负责加载 JVM 运行时核心类,加载System.getProperty("sun.boot.class.path")所指定的路径或jar

ExtensionClassLoader

负责加载 JVM 扩展类,比如 swing 系列、内置的 js 引擎、xml 解析器 等等,这些库名通常以 javax 开头,它们的 jar 包位于 JAVAHOME/lib/rt.jar文件中.

加载System.getProperty("java.ext.dirs")所指定的路径或jar。在使用Java运行程序时,也可以指定其搜索路径,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld。

AppClassLoader

才是直接面向我们用户的加载器,它会加载 Classpath 环境变量里定义的路径中的 jar 包和目录。我们自己编写的代码以及使用的第三方 jar 包通常都是由它来加载的。

加载System.getProperty("java.class.path")所指定的路径或jar。在使用Java运行程序时,也可以加上-cp来覆盖原有的Classpath设置,例如: java -cp ./lavasoft/classes HelloWorld

Tomcat的 类加载顺序

 

 

 

  在Tomcat中,默认的行为是先尝试在Bootstrap和Extension中进行类型加载,如果加载不到则在WebappClassLoader中进行加载,如果还是找不到则在Common中进行查找。

 

 NoClassDefFoundError

NoClassDefFoundError是在开发JavaEE程序中常见的一种问题。该问题会随着你所使用的JavaEE中间件环境的复杂度以及应用本身的体量变得更加复杂,尤其是现在的JavaEE服务器具有大量的类加载器。

在JavaDoc中对NoClassDefFoundError的产生是由于JVM或者类加载器实例尝试加载类型的定义,但是该定义却没有找到,影响了执行路径。换句话说,在编译时这个类是能够被找到的,但是在执行时却没有找到

这一刻IDE是没有出错提醒的,但是在运行时却出现了错误。

NoSuchMethodError

在另一个场景中,我们可能遇到了另一个错误,也就是NoSuchMethodError。

NoSuchMethodError代表这个类型确实存在,但是一个不正确的版本被加载了。

ClassCastException

ClassCastException,在一个类加载器的情况下,一般出现这种错误都会是在转型操作时,比如:A a = (A) method();,很容易判断出来method()方法返回的类型不是类型A,但是在 JavaEE 多个类加载器的环境下就会出现一些难以定位的情况。

posted @ 2020-11-17 16:19  哥的头像很别致~  阅读(471)  评论(0编辑  收藏  举报