五. Tomcat 常见问题解决及面试题
1. Tomcat 版本升级
2. Tomcat 常见面试题
1. Tomcat 有哪几种部署方式?
隐式部署
直接丢文件夹、war、jar 到 webapps 目录,tomcat 会根据文件夹名称自动生成虚拟路径,简单,但是需要重启 Tomcat 服务器,包括要修改端口和访问路径的也需要重启。
显式部署
添加 context 元素
server.xml 中的 Host 加入一个 Context(指定路径和文件地址),例如:
<Host name="localhost">
<Context path="/comet" docBase="D:\work_tomcat\app.war" />
即/comet 这个虚拟路径映射到了 D:\work_tomcat\ref-comet 目录下(war 会解压成文件),修改完 servler.xml 需要重启 tomcat 服务器。
创建 xml 文件
在 conf/Catalina/localhost 中创建 xml 文件,访问路径为文件名,例如:
在 localhost 目录下新建 demo.xml,内容为:
<Context docBase="D:\work_tomcat\app" />
不需要写 path,虚拟目录就是文件名 demo,path 默认为/demo,添加 demo.xml 不需要重启 tomcat 服务器。
三种方式比较:
隐式部署:可以很快部署,需要人手动移动 Web 应用到 webapps 下,在实际操作中不是很人性化
添加 context 元素 : 配置速度快,需要配置两个路径,如果 path 为空字符串,则为缺省配置,每次修改 server.xml 文件后都要重新启动 Tomcat 服务器,重新部署.
创建 xml 文件:服务器后台会自动部署,修改一次后台部署一次,不用重复启动 Tomcat 服务器,该方式显得更为智能化。
2. Tomcat 核心组件是哪些
Tomcat 的核心组件是链接器(connector)和容器(Container),
链接器(connector)封装了底层的网络请求(Socket 请求及相应处理),提供了统一的接口.
容器(Container)则专注处理 Servlet,Tomcat 本质上就是 Servlet 容器。
3. 什么是 Tomcat 的 Valve
在一个大的组件中直接处理这些繁杂的逻辑处理,使用管道(pipeline)可以把多个对象连接起来,而 Valve(阀门)整体看起来就像若干个阀门嵌套在管道中,而处理逻辑放在阀门上。
管道(Pipeline)就像一个工厂中的生产线,负责调配工人(valve)的位置,valve 则是生产线上负责不同操作的工人。
4. Tomcat 有哪几种 Connector 运行模式(优化)?
-
bio(blocking I/O) 同步阻塞 I/O (tomcat8.5 版本已经移除)
-
nio(non-blocking I/O) 同步非阻塞 I/O
-
Nio2/AIO 异步非阻塞 I/0
-
apr(Apache Portable Runtime/Apache 可移植运行库)
对于 I/0 选择,要根据业务场景来定,一般高并发场景下,APR 和 NIO2 的性能要优于 NIO 和 BIO,(linux 操作系统支持的 NIO2 由于是一个假的,并没有真正实现 AIO,所以一般 linux 上推荐使用 NIO,如果是 APR 的话,需要安装 APR 库,而 Windows 上默认安装了),所以在 8.5 的版本中默认是 NIO。
5. tomcat 容器是如何创建 servlet 类实例?用到了什么原理?
当容器启动时,会读取在 webapps 目录下所有的 web 应用中的 web.xml 文件,然后对 xml 文件进行解析,并读取 servlet 注册信息。然后,将每个应用中注册的 servlet 类都进 行加载,并通过反射的方式实例化(也有可能是在第一次请求时实例化)。
6. tomcat 如何优化?
Connector优化
使用线程池
关闭Valve
关闭自动重载和热部署方式
7. tomcat 中 JVM 如何调优
一般我们优化启动时的堆内存设置,Windows 下,在文件{tomcat_home}/bin/catalina.bat,Unix 下,在文件 C A T A L I N A H O M E / b i n / c a t a l i n a . s h 的 前 面 , 增 加 如 下 设 置 : J A V A O P T S = ” ‘ CATALINA_HOME/bin/catalina.sh 的前面,增加如下设置: JAVA_OPTS=”‘ CATALINAHOME/bin/catalina.sh的前面,增加如下设置:JAVAOPTS=”‘JAVA_OPTS” -Xms[初始化内存大小] -Xmx[可以使用的最大内存]
一般说来,你应该使用物理内存的 80% 作为堆大小。建议设置为 70%;建议设置[[初始化内存大小]等于[可以使用的最大内存],这样可以减少平凡分配堆而降低性能。
8. 说出 Tomcat中用到的任意一种设计模式?
管道模式(容器组件的启动流程)
责任链模式(Servlet链处理请求)
工厂模式(Bootstrap启动类中的初始化类加载器)
模板设计模式(类加载器的继承WebappClassloader)
9. Tomcat 中类加载的顺序
当应用需要到某个类时,则会按照下面的顺序进行类加载:
1 使用 bootstrap 引导类加载器加载
2 使用 system 系统类加载器加载
3 使用应用类加载器在 WEB-INF/classes 中加载
4 使用应用类加载器在 WEB-INF/lib 中加载
5 使用 common 类加载器在 CATALINA_HOME/lib 中加载
10. 什么是双亲委派模型?
为什么叫做双亲委派?
可以这样理解, 对于我们应用类加载器(应用也是我们关注的核心, jdk不是), 它只有两个上级, 父和父的父, 所以叫做双亲委派
11. 既然 Tomcat 不遵循双亲委派机制,那么如果我自己定义一个恶意的 HashMap,会不会有风险呢?
不会有风险,如果有,Tomcat 都运行这么多年了,那群 Tomcat 大神能不改进吗? tomcat 不遵循双亲委派机制,只是自定义的 webAppclassLoader 不遵循,但上层的类加载器还是遵守双亲委派的,