您当前的位置:首页 > 电脑百科 > 站长技术 > 服务器

Tomcat深入解析与性能优化

时间:2020-11-11 10:59:24  来源:  作者:
Tomcat深入解析与性能优化

 

前言

 

JAVA 应用中,常用的 Web 服务器一般由 Tomcat、weblogic、jetty、undertwo等。但从 Java 2019和2020 生态使用报告可以看到,tomcat的用户量对比明显较大,当然这也基于它开源和免费的特点。

 

Java 2019 年生态圈使用报告

Tomcat深入解析与性能优化

 

2020 Java 生态系统报告

Tomcat深入解析与性能优化

 

从软件架构的发展角度来看,软件架构大致经历了如下几个阶段:

Tomcat深入解析与性能优化

 

从 Java Web 角度来说,架构大致经历了:

Tomcat深入解析与性能优化

 

从当前企业使用的架构角度来说,使用SSM架构项目比较多,SSH基本被淘汰(大部分是老项目维护),很大一部分企业转向微服务架构了。

 

基于Spring 生态来说,大部分中小型企业都基本使用SpringBoot,SpringBoot本身集成了 tomcat、jetty和undertwo 容器,那么我们为什么需要花时间来研究tomcat呢?

  1. 当前tomcat依然是主流java web容器,研究它符合java 技术生态发展;
  2. 在java web项目调优中,如ssm项目中,在优化项目时,jvm和tomcat同样重要,都需要优化;
  3. 尽管springboot内置了tomcat容器,且配置了默认的tomcat参数,但当默认的tomcat参数满足不了项目优化要求时,就需要优化人员手动进行相关的参数优化,因此研究tomcat非常必要;
  4. 熟悉tomcat架构,是后续进行项目优化的基础,也是必备条件。

Tomcat架构说明


知识点:

 

  1. Tomcat目录结构
  2. Tomcat简要架构
  3. Tomcat各组件及关系
  4. Tomcat server.xml配置详解
  5. Tomcat启动参数说明(启动脚本)

 

Tomcat 是一个基于JAVA的WEB容器,其实现了JAVA EE中的 Servlet 与 jsp 规范,与Nginx Apache 服务器不同在于一般用于动态请求处理。在架构设计上采用面向组件的方式设计。即整体功能是通过组件的方式拼装完成。另外每个组件都可以被替换以保证灵活性。

Tomcat深入解析与性能优化

 

通过Tomcat官方可以看到,目前已经更新到Tomcat 10了,但当前大部分企业使用的Tomcat 为8或者9版本。

Tomcat深入解析与性能优化

 

Tomcat 目录结构

Tomcat深入解析与性能优化

 

  • bin:可执行文件,.sh结尾的表示linux可执行文件,.bat结尾的表示windows可执行文件
  • conf:配置文件
  • lib:tomcat相关jar包
  • temp:临时文件
  • webApps:存放项目
  • work:工作目录

bin目录

 

bin目录存放可执行文件,简要结束常用命令

Tomcat深入解析与性能优化

 

这里主要解释如下通用的命令,其他命令就不一一介绍

  • catalina.sh 真正启动Tomcat文件,可以在里面设置jvm参数
  • startup.sh 程序项目命令文件
  • version.sh 查看tomcat版本相关信息命令文件
  • shutdown.sh 关闭程序命令

 

conf目录

 

conf文件夹用来存放tomcat相关配置文件

Tomcat深入解析与性能优化

 

1.catalina.policy

 

项目安全文件,用来防止欺骗代码或JSP执行带有像System.exit(0)这样的命令的可能影响容器的破坏性代码. 只有当Tomcat用-security命令行参数启动时这个文件才会被使用,即启动tomcat时, startup.sh -security 。

Tomcat深入解析与性能优化

 

上图中,tomcat容器下部署两个项目,项目1和项目2。由于项目1中有代码System.exit(0),当访问该代码时,该代码会导致整个tomcat停止,从而也导致项目2停止。

 

为了解决因项目1存在欺骗代码或不安全代码导致损害Tomcat容器,从而影响其他项目正常运行的问题,启动tomcat容器时,加上-security参数就,即startup.sh -security,如此即使项目1中有代码System.exit(0),也只会仅仅停止项目1,而不会影响Tomcat容器,然而起作用的配置文件就是catalina.policy文件。

 

2.catalina.properties

 

配置tomcat启动相关信息文件

 

3.context.xml

 

监视并加载资源文件,当监视的文件发生发生变化时,自动加载

Tomcat深入解析与性能优化

 

 

4.jaspic-providers.xml 和 jaspic-providers.xsd

 

这两个文件不常用

 

5.logging.properties

 

该文件为tomcat日志文件,包括配置tomcat输出格式,日志级别等

 

6.server.xml

 

tomcat核心架构主件文件,下面会详细解析。

 

7.tomcat-users.xml和tomcat-users.xsd

 

tomcat用户文件,如配置远程登陆账号

 

tomcat-users.xsd 为tomcat-users.xml描述和约束文件

 

8.web.xml

 

tomcat全局配置文件。

 

lib目录

 

lib文件夹主要用来存放tomcat依赖jar包,如下为 tomcat 的lib文件夹下的相关jar包。

Tomcat深入解析与性能优化

 

每个jar包功能,这里就不讲解了,这里主要分析ecj-4.13.jar,这个jar包起到将.java编译成.class字节码作用。

 

假设要编译MyTest.java,那么jdk会执行两步:

  • 第一步:将MyTest.java编译成MyTest.class

javac MyTest.java

  • 第二步:执行MyTest.class

java MyTest.class

  • 那么,使用ecj-4.13.jar如执行MyTest.java呢?

java -jar ecj-4.13.jar MyTest.java

 

logs目录

 

该文件夹表示tomcat日志文件,大致包括如下六类文件:

Tomcat深入解析与性能优化

 


Tomcat深入解析与性能优化

 

temp目录

 

temp目录用户存放tomcat在运行过程中产生的临时文件。(清空不会对tomcat运行带来影响)。

 

webapps目录

 

webapps目录用来存放应用程序,当tomcat启动时会去加载webapps目录下的应用程序。可以以文件夹、war包、jar包的形式发布应用。

当然,你也可以把应用程序放置在磁盘的任意位置,在配置文件中映射好就行。

 

work目录

 

work目录用来存放tomcat在运行时的编译后文件,例如JSP编译后的文件。

清空work目录,然后重启tomcat,可以达到清除缓存的作用。

 

Tomcat 简要架构

 

Tomcat深入解析与性能优化

 

Tomcat 各组件及关系

  • Server 和 Service
  • Connector 连接器
    • HTTP 1.1
    • SSL https
    • AJP( Apache JServ Protocol) apache 私有协议,用于apache 反向代理Tomcat
  • Container
    • Engine 引擎 catalina
    • Host 虚拟机 基于域名 分发请求
    • Context 隔离各个WEB应用 每个Context的 ClassLoader都是独立
  • Component
    • Manager (管理器)
    • logger (日志管理)
    • loader (载入器)
    • pipeline (管道)
    • valve (管道中的阀)

 

Tomcat深入解析与性能优化

 

Tomcat server.xml 配置详解


Server 的基本基本配置:

<Server>
    <Listener /><!-- 监听器 -->
    <GlobaNamingResources> <!-- 全局资源 -->
    </GlobaNamingResources
    <Service>          <!-- 服务 用于 绑定 连接器与 Engine -->
        <Connector 8080/> <!-- 连接器-->
        <Connector 8010 /> <!-- 连接器-->
        <Connector 8030/> <!-- 连接器-->
        
        <Engine>      <!-- 执行引擎-->
            <Logger />
            <Realm />
               <host "www.test.com" appBase="">  <!-- 虚拟主机-->
                   <Logger /> <!-- 日志配置-->
                   <Context "/applction" path=""/> <!-- 上下文配置-->
               </host>
        </Engine>
    </Service>
</Server>

 

server

root元素:server 的顶级配置

主要属性:

port:执行关闭命令的端口号

shutdown:关闭命令

 

  • 演示shutdown的用法
#基于telent 执行SHUTDOWN 命令即可关闭
telent 127.0.0.1 8005
SHUTDOWN

 

service

 

服务:将多个connector 与一个Engine组合成一个服务,可以配置多个服务。

 

Connector

 

连接器:用于接收 指定协议下的连接 并指定给唯一的Engine 进行处理。

 

主要属性:

  • protocol 监听的协议,默认是http/1.1
  • port 指定服务器端要创建的端口号
  • minThread 服务器启动时创建的处理请求的线程数
  • maxThread 最大可以创建的处理请求的线程数
  • enableLookups 如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址
  • redirectPort 指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
  • acceptCount 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认100;
  • address 绑定客户端特定地址,127.0.0.1
  • bufferSize 每个请求的缓冲区大小 bufferSize * maxThreads
  • compression 是否启用文档压缩
  • compressionMinSize 文档压缩的最小大小
  • compressableMimeTypes text/html,text/xml,text/plain
  • connectionTimeout 客户端发起链接到服务端接收为止,指定超时的时间数(以毫秒为单位)
  • connectionUploadTimeout upload情况下连接超时时间
  • disableUploadTimeout 如果为true则使用 connectionTimeout
  • keepAliveTimeout 当长链接闲置 指定时间主动关闭 链接 ,前提是客户端请求头 带上这个 head"connection" " keep-alive"
  • maxKeepAliveRequests 最大的 长连接数 默认最大100
  • maxSpareThreads BIO 模式下 最多线闲置线程数
  • minSpareThreads BIO 模式下 最小线闲置线程数
  • SSLEnabled 是否开启 sll 验证,在Https 访问时需要开启。

 

  • 演示配置多个Connector
 <Connector port="8860" protocol="org.apache.coyote.http11.Http11NioProtocol"
                connectionTimeout="20000"
                redirectPort="8862"
                URIEncoding="UTF-8"
                useBodyEncodingForURI="true"
                compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/plain,text/JavaScript,text/css,application/x-json,application/json,application/x-javascript"
                maxThreads="1024" minSpareThreads="200"
                acceptCount="800"
                enableLookups="false"
        />

 

Engine

 

引擎:用于处理连接的执行器,默认的引擎是catalina。一个service 中只能配置一个Engine。

主要属性:name 引擎名称 defaultHost 默认host

 

Host

虚拟机:基于域名匹配至指定虚拟机。类似于nginx 当中的server,默认的虚拟机是localhost.

  • 演示配置多个Host
<Host name="www.test.com"  appBase="/usr/www/test"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"               prefix="www.luban.com.access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
</Host>

 

Context

 

应用上下文:一个host 下可以配置多个Context ,每个Context 都有其独立的classPath。相互隔离,以免造成ClassPath 冲突。

 

  • 演示配置多个Context
<Context docBase="hello" path="/h" reloadable="true"/>

 

Valve

 

阀门:可以理解成request 的过滤器,具体配置要基于具体的Valve 接口的子类。以下即为一个访问日志的Valve.

 

 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="www.luban.com.access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

 

Tomcat启动参数说明

 

我们平时启动Tomcat过程是怎么样的?

  1. 复制WAR包至Tomcat webapp 目录。
  2. 执行starut.bat 脚本启动。
  3. 启动过程中war 包会被自动解压装载。

但是我们在Eclipse 或idea 中启动WEB项目的时候 也是把War包复杂至webapps 目录解压吗?显然不是,其真正做法是在Tomcat程序文件之外创建了一个部署目录,在一般生产环境中也是这么做的 即:Tomcat 程序目录和部署目录分开 。

我们只需要在启动时指定CATALINA_HOME 与 CATALINA_BASE 参数即可实现。

Tomcat深入解析与性能优化

 

可以编写一个脚本 来实现自定义配置:

更新 启动 脚本

#!/bin/bash -e
export now_time=$(date +%Y-%m-%d_%H-%M-%S)
echo "deploy time:$now_time"

app=$1
version=$2
mkdir -p war/
#从svn下载程序至 war目录
war=war/${app}_${version}.war
echo "$war"
svn export svn://192.168.0.253/release/${app}_${version}.war $war

deploy_war() {
#解压版本至当前目录
target_dir=war/${app}_${version}_${now_time}
unzip -q $war -d $target_dir
rm -f appwar
ln -sf $target_dir appwar
target_ln=`pwd`/appwar
echo '<?xml version="1.0" encoding="UTF-8" ?>
<Context docBase="'$target_ln'" allowLinking="false">
</Context>' > conf/Catalina/localhost/ROOT.xml
#重启Tomcat服务
./tomcat.sh restart
}

deploy_war
```

 

自动部署脚本

#!/bin/bash -e
export now_time=$(date +%Y-%m-%d_%H-%M-%S)
echo "deploy time:$now_time"

app=$1
version=$2
mkdir -p war/
#从svn下载程序至 war目录
war=war/${app}_${version}.war
echo "$war"
svn export svn://192.168.0.253/release/${app}_${version}.war $war

deploy_war() {
#解压版本至当前目录
target_dir=war/${app}_${version}_${now_time}
unzip -q $war -d $target_dir
rm -f appwar
ln -sf $target_dir appwar
target_ln=`pwd`/appwar
echo '<?xml version="1.0" encoding="UTF-8" ?>
<Context docBase="'$target_ln'" allowLinking="false">
</Context>' > conf/Catalina/localhost/ROOT.xml
#重启Tomcat服务
./tomcat.sh restart
}

deploy_war
```

 

Tomcat 网络通信模型剖析


Tomcat 支持四种线程模型介绍

 

什么是IO?

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

Tomcat深入解析与性能优化

 

什么是IO模型?

 

提问:

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

 

演示:

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

 

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

 

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

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

Tomcat深入解析与性能优化

 

使用指定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的线程数的变化?

Tomcat深入解析与性能优化

 

BIO 配置

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Protocol"
               connectionTimeout="20000"
               redirectPort="8443"
               compression="on" compressionMinSize="1024"
               compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/x-json,application/json,application/x-javascript"
               maxThreads="500" minSpareThreads="1"/>

 

NIO配置

 <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               redirectPort="8443"
               compression="on" compressionMinSize="1024"
               compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/x-json,application/json,application/x-javascript"
               maxThreads="500" minSpareThreads="1"/>

 

演示数据:

Tomcat深入解析与性能优化

 

生成环境重要因素:

  1. 网络
  2. 程序执行业务用时

 

源代码地址:https://github.com/org-hejianhui/bit-bigdata-transmission

 

BIO 线程模型

Tomcat深入解析与性能优化

 

BIO 源码

 

线程组:

Accept 线程组 acceptorThreadCount 默认1个

exec 线程组 maxThread

JIoEndpoint

Acceptor extends Runnable

SocketProcessor extends Runnable

Tomcat深入解析与性能优化

 

NIO 线程模型

Tomcat深入解析与性能优化

 

NIO 线程模型

 

Accept 线程组 默认两个轮询器

Poller Selector PollerEvent轮询线程状态

SocketProcessor

Tomcat深入解析与性能优化

 

 

BIO

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

 

NIO

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

 

Tomcat connector 并发参数解读

 

Tomcat深入解析与性能优化

 

Tomcat 类加载机制源码解析

 

类加载的本质

 

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

 

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

 

jvm里ClassLoader的层次结构

Tomcat深入解析与性能优化

 

类加载器层次结构

 

BootstrapClassLoader(启动类加载器)

 

称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件:

URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL url : urLs) {
    System.out.println(url.toExternalForm());
}

程序执行结果如下:

file:/Library/Java/JavaVirtualmachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/resources.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/rt.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/sunrsasign.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jsse.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jce.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/charsets.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/jfr.jar
file:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/classes

从rt.jar中选择String类,看一下String类的类加载器是什么

ClassLoader classLoader = String.class.getClassLoader();
System.out.println(classLoader);

执行结果如下:

null

 

可知由于BootstrapClassLoader对Java不可见,所以返回了null,我们也可以通过某一个类的加载器是否为null来作为判断该类是不是使用BootstrapClassLoader进行加载的依据。

 

ExtensionClassLoader

 

ExtClassLoader称为扩展类加载器,主要负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包或者由java.ext.dirs系统属性指定的jar包.放入这个目录下的jar包对AppClassLoader加载器都是可见的(因为ExtClassLoader是AppClassLoader的父加载器,并且Java类加载器采用了委托机制)。

 

ExtClassLoader的类扫描路径通过执行下面代码来看一下:

String extDirs = System.getProperty("java.ext.dirs");
for (String path : extDirs.split(";")) {
System.out.println(path);
}

执行结果如下(Mac系统):

/Users/hjh/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java

jre/lib/ext路径下内容为:

Tomcat深入解析与性能优化

 

从上面的路径中随意选择一个类,来看看它的类加载器是什么:

sun.misc.Launcher$ExtClassLoader@4439f31e
null

从上面的程序运行结果可知ExtClassLoader的父加载器为null,之前说过BootstrapClassLoader对Java不可见,所以返回了null。ExtClassLoader的父加载器返回的是null,那是否说明ExtClassLoader的父加载器是BootstrapClassLoader?

 

Bootstrap ClassLoader是由C/C++编写的,它本身是虚拟机的一部分,所以它并不是一个JAVA类,也就是无法在java代码中获取它的引用,JVM启动时通过Bootstrap类加载器加载rt.jar等核心jar包中的class文件,之前的int.class,String.class都是由它加载。然后呢,我们前面已经分析了,JVM初始化sun.misc.Launcher并创建Extension ClassLoader和AppClassLoader实例。并将ExtClassLoader设置为AppClassLoader的父加载器。Bootstrap没有父加载器,但是它却可以作用一个ClassLoader的父加载器。比如ExtClassLoader。这也可以解释之前通过ExtClassLoader的getParent方法获取为Null的现象

 

AppClassLoader

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

 

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

 

public class AppClassLoaderTest {
    public static void main(String[] args) {
        System.out.println(ClassLoader.getSystemClassLoader());
    }
}

 

输出结果如下:

sun.misc.Launcher$AppClassLoader@18b4aac2

 

以上结论说明调用ClassLoader.getSystemClassLoader()可以获得AppClassLoader类加载器。

protected ClassLoader() {
    this(checkCreateClassLoader(), getSystemClassLoader());
}

通过查看ClassLoader的源码发现并且在没有特定说明的情况下,用户自定义的任何类加载器都将该类加载器作为自定义类加载器的父加载器。

 

通过执行上面的代码即可获得classpath的加载路径。

 

在上面的main函数的类的加载就是使用AppClassLoader加载器进行加载的,可以通过执行下面的代码得出这个结论

public class AppClassLoaderTest {

    public static void main(String[] args) {
        ClassLoader classLoader = Test.class.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
    }

    private static class Test {

    }

}

 

执行结果如下:

sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@2d209079

从上面的运行结果可以得知AppClassLoader的父加载器是ExtClassLoader

 

Tomcat的 类加载顺序

 

Tomcat深入解析与性能优化

 

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

 

NoClassDefFoundError

 

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

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

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

 

NoSuchMethodError

 

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

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

 

ClassCastException

 

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

 

部分图片来源于网络,版权归原作者,侵删。


Tags:Tomcat   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1. 整体架构简析#如果将Tomca它的结构高度抽象的话,那么Tomcat其实可以看成只是有连接器(Connector)和容器(Container)两个组件构成。其中Connector组件负责在服务器端处理客户端...【详细内容】
2021-09-30  Tags: Tomcat  点击:(53)  评论:(0)  加入收藏
开源的 Java Web 应用服务器,实现了 Java EE(Java Platform Enterprise Edition)的部 分技术规范,比如 Java Servlet、Java Server Page、JSTL、Java WebSocket。Java EE 是 S...【详细内容】
2021-09-17  Tags: Tomcat  点击:(68)  评论:(0)  加入收藏
一、前言server.xml 配置,是 Tomcat启动配置,从配置结构可以看出 Tomcat 的整体架构。如果能够了解其常用配置项,对 Tomcat有一个高屋建瓴的把握,然后再庖丁解牛,一步步深入源码...【详细内容】
2021-07-04  Tags: Tomcat  点击:(86)  评论:(0)  加入收藏
一,undertow介绍 1,undertow简介:Undertow是RedHAT红帽公司开源的产品,采用java开发,是一款灵活,高性能的web服务器,提供了NIO的阻塞/非阻塞API,也是Wildfly的默认Web容器。在javaw...【详细内容】
2021-05-07  Tags: Tomcat  点击:(184)  评论:(0)  加入收藏
说明最近项目上遇到一些https的问题,需要在tomcat里面测试一下如何开启https协议访问网站,在网上查了一些资料,自己也试了很多次,终于成功搞定了,下面跟大家分享一下我的一点经验...【详细内容】
2021-04-20  Tags: Tomcat  点击:(162)  评论:(0)  加入收藏
1 Jetty与glassfish的基本介绍1.1 研究背景及意义下图是对几个主流的应用服务器使用比率的粗率统计结果做出的一个饼图。这个图的数据也许不够精确,但它还是可以在一定程度上...【详细内容】
2021-04-06  Tags: Tomcat  点击:(199)  评论:(0)  加入收藏
Tomcat是什么?Tomcat是web容器。你在做web项目时,多数需要http协议,也就是基于请求和响应,比如你在百度输入一行内容搜索,那么百度服务器如何处理这个请求呢,他需要创建servlet来...【详细内容】
2021-03-24  Tags: Tomcat  点击:(290)  评论:(0)  加入收藏
有这样一个场景,公司为了安全起见,需要对所有登录Linux服务器做安全限制,要求除了管理员其他要登录linux服务器的员工不能用最高权限账号登录,要创建新的用户,对目录及文件权限做...【详细内容】
2021-03-04  Tags: Tomcat  点击:(178)  评论:(0)  加入收藏
热部署就是在服务器运行时重新部署项目,热加载即在在运行时重新加载class,从而升级应用。通常情况下在开发环境中我们使用的是热加载,因为热加载的实现的方式在Web容器中启动一...【详细内容】
2021-03-03  Tags: Tomcat  点击:(210)  评论:(0)  加入收藏
制作tomcat镜像先找到一个要安装的版本我们这里以拉取tomcat8的官方镜像为例 1:拉取官方镜像docker pull tomcat:8 2:查看镜像并启动tomcat容器docker imagesdocker run -d -p...【详细内容】
2021-03-01  Tags: Tomcat  点击:(323)  评论:(0)  加入收藏
▌简易百科推荐
阿里云镜像源地址及安装网站地址https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b111kK44P更新源之前把之前的国外的镜像先备份一下 切换到yumcd...【详细内容】
2021-12-27  干程序那些事    Tags:CentOS7镜像   点击:(1)  评论:(0)  加入收藏
前言在实现TCP长连接功能中,客户端断线重连是一个很常见的问题,当我们使用netty实现断线重连时,是否考虑过如下几个问题: 如何监听到客户端和服务端连接断开 ? 如何实现断线后重...【详细内容】
2021-12-24  程序猿阿嘴  CSDN  Tags:Netty   点击:(12)  评论:(0)  加入收藏
一. 配置yum源在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repovim /etc/yum.repos.d/google-chrome.repo按i进入编辑模式写入如下内容:[google-chrome]name=googl...【详细内容】
2021-12-23  有云转晴    Tags:chrome   点击:(7)  评论:(0)  加入收藏
一. HTTP gzip压缩,概述 request header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据 response body,同时加入以下header:Content-Encoding: gzip:表明bo...【详细内容】
2021-12-22  java乐园    Tags:gzip压缩   点击:(8)  评论:(0)  加入收藏
yum -y install gcc automake autoconf libtool makeadduser testpasswd testmkdir /tmp/exploitln -s /usr/bin/ping /tmp/exploit/targetexec 3< /tmp/exploit/targetls -...【详细内容】
2021-12-22  SofM    Tags:Centos7   点击:(7)  评论:(0)  加入收藏
Windows操作系统和Linux操作系统有何区别?Windows操作系统:需支付版权费用,(华为云已购买正版版权,在华为云购买云服务器的用户安装系统时无需额外付费),界面化的操作系统对用户使...【详细内容】
2021-12-21  卷毛琴姨    Tags:云服务器   点击:(6)  评论:(0)  加入收藏
参考资料:Hive3.1.2安装指南_厦大数据库实验室博客Hive学习(一) 安装 环境:CentOS 7 + Hadoop3.2 + Hive3.1 - 一个人、一座城 - 博客园1.安装hive1.1下载地址hive镜像路径 ht...【详细内容】
2021-12-20  zebra-08    Tags:Hive   点击:(9)  评论:(0)  加入收藏
以下是服务器安全加固的步骤,本文以腾讯云的CentOS7.7版本为例来介绍,如果你使用的是秘钥登录服务器1-5步骤可以跳过。1、设置复杂密码服务器设置大写、小写、特殊字符、数字...【详细内容】
2021-12-20  网安人    Tags:服务器   点击:(7)  评论:(0)  加入收藏
项目中,遇到了一个问题,就是PDF等文档不能够在线预览,预览时会报错。错误描述浏览器的console中,显示如下错误:nginx代理服务报Mixed Content: The page at ******** was loaded...【详细内容】
2021-12-17  mdong    Tags:Nginx   点击:(7)  评论:(0)  加入收藏
转自: https://kermsite.com/p/wt-ssh/由于格式问题,部分链接、表格可能会失效,若失效请访问原文密码登录 以及 通过密钥实现免密码登录Dec 15, 2021阅读时长: 6 分钟简介Windo...【详细内容】
2021-12-17  LaLiLi    Tags:SSH连接   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条