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 多个类加载器的环境下就会出现一些难以定位的情况。

  • 相关阅读:
    解决SharePoint 文档库itemadded eventhandler导致的上传完成后,编辑页面保持报错的问题,错误信息为“该文档已经被编辑过 the file has been modified by...”
    解决SharePoint 2013 designer workflow 在发布的报错“负载平衡没有设置”The workflow files were saved but cannot be run.
    随机实例,随机值
    Spring4笔记
    struts2笔记(3)
    struts2笔记(2)
    获取文本的编码类型(from logparse)
    FileUtil(from logparser)
    DateUtil(SimpleDateFormat)
    struts2笔记
  • 原文地址:https://www.cnblogs.com/scote/p/13994858.html
Copyright © 2011-2022 走看看