zoukankan      html  css  js  c++  java
  • 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 estprojclasses 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 多个类加载器的环境下就会出现一些难以定位的情况。

  • 相关阅读:
    指针
    显示和隐式转换
    C++虚函数
    字符串输出
    BP神经网络
    超像素分割
    函数putText()在图片上写文字
    compare
    十五、cookies和session的使用
    爬取腾讯社招职位信息
  • 原文地址:https://www.cnblogs.com/scote/p/13994858.html
Copyright © 2011-2022 走看看