Tomcat面试必备
2025-09-09 09:58:04 0 举报
AI智能生成
当准备面试涉及Tomcat服务器的职位时,关键是要熟悉Tomcat的架构及其核心组件。Tomcat,作为Apache软件基金会的一个顶级项目,是一个开源的Java Servlet容器,广泛用于部署和运行JavaServer Pages (JSP)和Servlet技术实现的web应用。 掌握Tomcat的内部工作原理是至关重要的。了解它的主要组件,如Connectors(负责网络连接)、Catalina(处理Servlet和JSP的容器)、Coyote(用于HTTP通信)、Jasper(JSP引擎)等。熟悉这些组件将帮助你理解Tomcat如何处理客户端请求和生成响应。 进一步深入,掌握Tomcat的配置文件(server.xml, web.xml等)及其作用域(全局、主机、上下文等)将显示你对细节的敏锐洞察力。理解其默认值以及如何进行适当调整是必要的。 另外,对Tomcat的性能调优,以及如何进行故障排查和安全加固的知识,都将让你在面试中脱颖而出。在面试中可能会被问及这些知识的实现方法,或者如何通过更改配置来优化特定性能指标。例如,如何通过连接器配置优化并发处理,或者如何配置安全证书来增强安全性。 在回答中运用恰当的修饰语,展现出对Tomcat面试必备知识的精通和热忱,可以让你在面试中更具有竞争力。例如:“我深入理解了Tomcat的架构设计,对其核心组件和配置文件有着详尽的掌握。对于如何优化Tomcat以实现高效的请求处理和卓越性能,我有着实战经验和深刻的见解。” 这样的回答展现了你的自信和专业。
作者其他创作
大纲/内容
应用程序部署的三种方式
将打包后的项目复制到webapps目录下面<br>
可通过修改host标签下的appBase,修改部署的目录
在server.xml中配置context<br>
在conf\Catalina\localhost 目录下创建一个已项目名为文件名的xml文件<br>
http://localhost:8080/webDemo/serveletDemo1结构
webDemo是项目访问路径<br>
会有一个xml映射真实的路径
serveletDemo1是servlet也可以是一个静态文件的相对地址
是servlet的时候对应的是servlet-mapping中的关系,找到对应的类
Jvm 类加载机制
三类加载器+自定义加载器
引导(启动)类加载器
负责加载核心类库,就是jre下面lib的<br>
扩展类加载器
在lib下面有一个ext扩展类的文件夹<br>
应用程序(系统)类加载器
负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类
自定义加载器
双亲委派机制
加载器在jvm中打印出来是什么
在jvm中,顶层加载器,也就是启动加载器打印是null<br>
扩展类加载器打印是ExtClassLoader<br>
应用程序加载器打印是AppclassLoader<br>
加载器的父子关系
应用程序加载器的加载器是扩展类加载器<br>
扩展类加载器的父加载器是启动加载器
当加载一个类的时候,首先在缓存中找,<br>
如果缓存中没有就从应用程序加载器加载
但是应用程序加载器会委托他的父加载器扩展类加载器加载
扩展类加载器也会先委托父加载器启动类加载器
启动类加载器如果加载成功就会缓存起来
如果启动类加载器没有加载成功,那么退给子类加载器自己加载
如果扩展类加载器没有加载成功,,退回给子类加载器
打破双亲委派机制
Tomcat自定义加载器WebAppClassLoader<br>
原理
在findClass方法中,首先去找web应用下的类<br>
也就是web应用部署的地方的Class文件和lib文件下的类<br>
如果没有找到就交给父加载器去找<br>
在loadClass方法中
首先在本地缓存中找是否已经加载了该类<br>
然后在系统加载器的缓存中找<br>
然后在扩展类加载器去加载
尝试在本地目录找<br>
最后用系统类加载器AppClassLoader加载<br>
这里才是跳出双亲委派机制之后,预防核心类库和扩展类被自定义类替代的地方
但是依然会过滤到核心类库和扩展类的加载
避免加载模仿核心类或扩展类的自定义类
Tomcat类加载器的层次结构<br>
CommonLoader,Tomcat最基本的加载器<br>
然后是WebApp共享的类sharedClassLoader:用于加载需要共享的类<br>
可以通过配置设置需要加载的共享类
底层是WebAppClassLoader:Webapp的私有加载器,用于隔离多个servlet<br>
他是context级别的加载,和context共存亡
Tomcat容器私有的类加载器CatalinaClassLoader,他并不是WebAppClassLoader的父加载器,他是独立的和ShardClassLoader加载器有共同的父加载器<br>
Spring的加载问题<br>
全盘负责委托机制<br>
谁加载Spring,谁负责加载业务类,所以Spring作为一个bean工厂,需要负责加载业务类<br>
但是Web应用之间共享的Jar包是由ShareClassLoader加载的,所以ShareClassLoader是不能直接加载业务类的<br>
线程上下文加载器
它是一种类加载传递机制<br>
类加载器是保存在线程的私有数据中,<br>
只要在同一个线程中,并且设置了上下文线程加载器<br>
就可以把这个加载器取出来使用
WebAppClassLoarder 类加载器,在启动 Web 应用的线程里设置线程上下文加载器
我们熟悉的 JDBC 就是通过上下文类加载器来加载不同的数据库驱动的
Tomcat和Spring热加载和热部署原理<br>
基本原理都是通过周期性任务实现
一种java sevlet 容器,<br>
是一种web服务器,用于在服务端运行java servlet 和JSP技术<br>
是一款高效、稳定和易于使用的Web服务器。<br>
idea相关设置和用法
idea添加tomcat server
在菜单的File->setting中<br>
选择左侧的 Build, Execution, Deployment -> Application Servers。
点击右侧的加号,选择 Tomcat Server。
选择 Tomcat 的安装目录,并设置 Tomcat 的 JRE 路径。
项目设置tomcat启动
Edit configuration<br>
左上角加好添加tomcat server - local<br>
右侧页面Deployment选项中添加需要运行的项目<br>
Application context可以设置servlet名字<br>
servlet接口
实现类可以接收并处理请求
两种配置方式
第一种是在web.xml中配置
第二种是通过注解:@WebServlet<br>
GenericServlet抽象类实现了servlet接口,并且有一些默认实现的方法,我们只需要处理service方法就行<br>
HttpServlet抽象类继承了GenericServlet,并且在servlet中区分了get、post等请求,只需要重写doGet、doPost等接口即可实现Http请求的处理
tomcat整体架构
tomcat核心功能
处理socket连接,负责网络字节流与request和response对象转化
加载管理servlet容器,以及处理具体的request
核心组件<br>
server,指的就是tomcat服务,包含多个service<br>
service组件,包含若干connector组件和处理请求的Engine组件<br>
不同的服务,需要修改不同的端口,在server.xml中添加service标签即可<br>
连接器connector<br>
监听固定端口接收外部请求,传递给 Container,并将Container<br>处理的结果返回给外部。
实现功能<br>
1 监听端口
2 接收网络请求<br>
3 读取网络字节流<br>
4 根据应用层协议,解析Http/AJP,生成统一的Tomcat request<br>
5 通过适配器(Adapter)转为ServletRequest<br>
6 调用servlet 容器,得到ServletResponse<br>
7 将ServletResponse转为网络字节流<br>
8 将响应返回给客户端<br>
高内聚<br>
根据实现的功能可以看出三个高内聚的功能
网络通信<br>
包含功能
1
2
3
8
EndPoint组件 : EndPoint负责提供字节流给Processor<br>
和IO模型的封装,他的实现类是AbstractEndPoint<br>
子类包含
NioEndPoint<br>
主从reactor多线程<br>
Nio2EndPoint
重要子组件
Acceptor<br>
用于监听socket请求<br>
在Nio模式下,他运行在一个单独的线程中,当收到请求的时候,accept方法会创建一个channel,并且将channel交给poller处理,poller本质上就是一个selector<br>
SocketProcessor<br>
用于处理接收到的socket请求<br>
EndPoint 是用来实现 TCP/IP 协议的。
应用层协议解析<br>
包含功能
4<br>
Procssor组件:Processor接收到字节流以后解析成TomcatRequest,提供给Adapter<br>
Tomcat Request/Response 与 Servlet Request/Response相互转化<br>
包含功能
5
7
Adapter组件:Adapter负责提供ServletRequest给容器<br>
低耦合
由于IO模型和应用层协议,可以自由组合,比如 NIO + HTTP 或者 NIO2 + AJP<br>
Tomcat 的设<br>计者将网络通信和应用层协议解析放在一起考虑,设计了一个叫 ProtocolHandler的接口来封装这两<br>种变化点。
ProtocolHandler包含两个重要组件
EndPoint
负责提供字节流给 Processor;
Processor
负责提供字节流给 Processor;
容器container<br>
分为四层
第一层:也叫顶层容器Engine<br>
第二层:Host<br>
第三层:context
第四层:wrapper<br>
表示一个 Servlet,最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创建、执行<br>和销毁
Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管理所有的 Web 资源。一<br>个Context对应一个 Web 应用程序。
负责 web 应用的部署和 Context 的创建
负责 web 应用的部署和 Context 的创建
通过父子容器,实现每一层的快速查找<br>
pipeline-value 责任链模式<br>
每个容器都可以看成是一个管道,多个管道连接在一起,形成一个链路,可以再每个管道上加载阀门(比如host加上黑名单)过滤条件<br>
对Tomcat核心组件的流程和理解
首先server就是Tomcat,可以包含多个service<br>
每个service代表一个服务或项目,每个服务有多个连接器
连接器负责监听端口,连接器用 ProtocolHandler 来处理网络连接和应用层协议<br>
Protocol有两个重要的组件,EndPoint和Processor
Endpoint负责底层的socket通讯,就是说Endpoint监听端口,接收和发送socket的处理器,是对传输层的抽象<br>
Endpoint的抽象类是AbstractEndiPoint,具体的子类包含NioEndPoint/Nio2EndPoint,<br>
在NioEndPoint子类中有两个重要的子组件
Acceptor线程监听socket链接,当检测到链接请求后会创建socketwapper对象,并将对象交给工作线程socketProcessor<br>
socketProcessor读取字节流解析成tomcat request,因为不是标准的servletRequest,所以他会调用adapter组件<br>
Adaptor会将tomcat request转化为servletRequest,并且找到容器调用pipeline的fisrt valve的invoke方法<br>
Adaptor通过找到service,在找到这个service上的容器
从这里开始就进入容器的流程了,首先容器里有pipeline-valve责任链模式,他是一个单向链表,<br>
第一个接收到请求的就是顶层容器Engine,他的first valve就是standarEngineValve<br>
Engine容器完成pipeline的任务后,找到对应的host容器,然后执行host的pipeline的fist valve的invoke方法<br>
Host容器找到对应的context容器,并且继续执行context的pipeline的first valve的invoke方法<br>
context容器找到对应的wrapper容器,这时候的wrapper管理的就是我们通常理解的servlet了,依然执行pipeline的first valve的invoke方法<br>
Processor,用于处理接收到的socket请求,<br>
Processor 用来实现 HTTP/AJP 协议
IO模型
Bio:阻塞式io<br>
Nio:非阻塞io<br>
不停的询问连接是否有消息,这里是两个循环,缺点是每次二循环都需要遍历socket,看是否有消息<br>
Nio seletor:io 复用<br>
多路复用选择器selector,可以理解为观察者模式
信号io
异步io,tomcat中是nio2EndPoint<br>
0 条评论
下一页