15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 程序猿必须知道的关于 Tomcat 的知识点

程序猿必须知道的关于 Tomcat 的知识点

时间:2023-07-12 08:24:02 | 来源:网站运营

时间:2023-07-12 08:24:02 来源:网站运营

程序猿必须知道的关于 Tomcat 的知识点:

身为 Java 程序员,Tomcat 应该算是我们接触的最多的 web 容器了。同时,作为企业生产工具的 “八阿哥” 们,平常只顾着埋头写 BUG,哪有什么时间整理用过的知识点。今天,我将和大家一起梳理一下关于 Tomcat 的相关内容,由浅入深,从入门到放弃。奥利给~!

一、HTTP 请求处理流程







如上图所示:

  1. 用户通过浏览器发起请求。
  2. 浏览器向目标服务器发起 TCP 连接请求。
  3. 经过三次握手后客户端浏览器与目标服务器成功建立 TCP 连接。(基于 Socket 实现)
  4. 浏览器生成 HTTP 格式的数据包。
  5. 浏览器发送 TCP 请求数据包。(这个数据包的请求头为 TCP 格式的请求头,上一步封装的HTTP 格式的数据包被作为 TCP 请求体传送至服务器)
  6. 服务器解析 TCP 请求体中的 HTTP 数据包。
  7. 服务器处理请求,完成相关业务逻辑。
  8. 服务器生成 HTTP 格式的响应数据包。
  9. 服务器将响应数据包发送至客户端浏览器。
  10. 浏览器解析 HTTP 格式的响应数据包。(解析出的数据为静态数据如:HTMLCSSJS、图片等)
  11. 浏览器渲染响应结果,呈现静态数据给用户。

二、Tomcat 总体架构说明







Tomcat 作为 Servlet 容器从软件运行角度看,主要可以分为两大模块,一个是 Http 请求接收、响应模块(Coyote),另一个是请求处理模块,即从 Servlet 容器中获取与请求对应的处理方法并执行(Catalina)。

Coyote 连接器包含以下两个模块:

  1. ProtocolHandler 协议处理接口。这个接口通过 EndpointProcessor ,实现针对具体协议的处 理能⼒。Tomcat 按照协议和 I/O 提供了6个实现类 : AjpNioProtocolAjpAprProtocolAjpNio2ProtocolHttp11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol
2. Adapter 由于请求协议的不同,客户端发送至后台的请求信息也不尽相同。为了能够转换成统一的 ServletRequestServletResponse 对象方便 Servlet 容器处理业务,则需要该接口的实现类,对发送至 Tomcat 的请求进行统一的适配处理。进而使调用 Servlet 容器中的方法变的简单。


Servlet 容器又名 Catalina。一个 Catalina 实例只能拥有一个 Server 实例,一个 Server 实例可以包含多个 Service 实例。而每一个 Service 实例又可以包含多个 Connector 和一个 Container。一个 Container 只能有一个 Engine,一个 Engine 可以有多个 Host ,每个 Host 可以包含多个 Context (网站),每个 Context 中可以有多个 WrapperServlet)。

  1. Catalina 实例可以被看成就是一个 Tomcat 实例。该实例用以解析 server.xml 配置文件, 以此来创建服务器Server组件并进⾏管理。
  2. Server 表示整个 Catalina Servlet 容器以及其它组件,负责组装并启动 Servlaet 引擎,Tomcat 连接器。
  3. ServiceServer 内部的组件,⼀个 Server 包含多个 Service。它将若⼲个 Connector 组件绑定到⼀个 Container。(通常情况下只用一个 Service 就够了)
  4. Container 负责处理⽤户的 servlet 请求,并将处理结果返回给用户。
Tips

上述组件的配置其实就体现在 Tomcat 软件中的 conf/server.xml 里。

三、Tomcat 核心配置文件 server.xml

问个实在的问题:当你第一次甚至说上一次看 Tomcat 的配置文件 server.xml 时,你的第一感受是啥?反正我最真切的感受就是:“我靠,英文真多~!”。不过静下心来再看,更多的都是说明性文字。删除注释后再看,就跟被拔光毛的鸡一样,也就那样。不信你看

<?xml version="1.0" encoding="UTF-8"?><!-- port:关闭服务器的监听端⼝ shutdown:关闭服务器的指令字符串 --><Server port="8005" shutdown="SHUTDOWN"> <!-- 以⽇志形式输出服务器 、操作系统、JVM的版本信息 --> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <!-- 加载(服务器启动)和销毁(服务器停⽌)APR。如果找不到 APR 库,则会输出⽇志,但并不影响 Tomcat 启动 --> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <!-- 避免JRE内存泄漏问题 --> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <!-- 加载(服务器启动)和销毁(服务器停⽌)全局命名服务 --> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <!-- 在Context停⽌时重建 Executor 池中的线程,以避免 ThreadLocal 相关的内存泄漏 --> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <!-- 全局命名服务,定义服务器的全局 JNDI 资源 --> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <!-- 处理 HTTP/1.1 协议的请求 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 处理 AJP/1.3 协议的请求 用不到的话可以注释掉 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" /> </Host> </Engine> </Service></Server>这么一整理是不是瞬间清爽了很多。需要注意的是,通常情况下,上面配置文件里添加了注释的部分,除了 Connector 标签中的参数,其他标签的内容一般不需要修改,保持默认即可。

四、核心配置文件进阶

4-1 <Service> 标签

<Service name="Catalina"> ...</Service>该标签⽤于创建 Service 实例,默认使⽤ org.apache.catalina.core.StandardService 对象。默认情况下,Tomcat 仅指定了 Service 的名称, 值为 "Catalina"。 Service ⼦标签有 : ListenerExecutorConnectorEngine。其中:

4-2 <Executor> 标签

该标签用于为 Service 添加线程池。默认情况下,在 server.xml 文件中,该标签是被注释掉的,即未开启线程池的。如果想开启,则打开注释,并配置相关属性即可。

<Executor name="commonThreadPool" namePrefix="thread-exec-" maxThreads="200" minSpareThreads="100" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" threadPriority="5" className="org.apache.catalina.core.StandardThreadExecutor"/><Executor> 标签属性含义

4-3 <Connector> 标签

该⽤于创建链接器实例默认情况下,server.xml 配置了两个链接器,⼀个⽀持 HTTP 协议,⼀个⽀持 AJP 协议⼤多数情况下,我们并不需要新增链接器配置,只是根据需要对已有链接器进⾏优化。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" executor="commonThreadPool" URIEncoding="UTF-8" minSpareThreads="100" maxThreads="1000" acceptCount="1000" maxConnections="1000" compression="on" compressionMinSize="2048" disableUploadTimeout="true" /><Connector> 标签属性含义

4-4 <Engine> 标签

<Engine name="Catalina" defaultHost="localhost"> ...</Engine>该标签表示 Servlet 引擎。其属性 name ⽤于指定 Engine 的名称, 默认为CatalinadefaultHost 属性用于指定默认使⽤的虚拟主机名称,当客户端请求指向的主机⽆效时,将交由默认的虚拟主机处理,默认为值 localhost

4-5 <Host> 标签

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> ...</Host>该标签用于配置⼀个虚拟主机。

4-6 <Context> 标签

<Host name="www.abc.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="/Users/yingdian/web_demo" path="/web_demo"></Context> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" /></Host><Host> 标签中的 <Context> 标签用于配置一个 Web 应用。

五、Tomcat 配置 HTTPS

  1. 使⽤ JDK 中的 keytool ⼯具⽣成免费的秘钥库⽂件(证书)。
keytool -genkey -alias SupremeSir -keyalg RSA -keystore supreme.keystore







2. 配置 server.xml

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="E:/**/apache-tomcat/bin/supreme.keystore" certificateKeystorePassword="123456" type="RSA"/> </SSLHostConfig></Connector>certificateKeystoreFile:指定证书所在位置。

certificateKeystorePassword:指定证书秘钥库口令。

六、Tomcat 性能优化

Tomcat 优化没有明确的参数值可以直接去使⽤,必须根据⾃⼰的真实⽣产环境来进⾏调整,调优是⼀个过程。调优主要从两个⽅⾯进⾏:

  1. JVM 虚拟机优化(优化内存模型)
  2. Tomcat ⾃身配置的优化

6-1 Java 虚拟机内存相关参数

参数参数作用优化建议
-server启动Server,以服务端模式运⾏服务端模式建议开启
-Xms最⼩堆内存建议与-Xmx设置相同
-Xmx最⼤堆内存建议设置为可⽤内存的80%
-XX:MetaspaceSize元空间初始值自行调整
-XX:MaxMetaspaceSize元空间最⼤内存默认⽆限
-XX:NewRatio年轻代和⽼年代⼤⼩⽐值,取值为整数,默认为2不需要修改
-XX:SurvivorRatioEden区与Survivor区⼤⼩的⽐值,取值为整数,默认为8不需要修改
bin/catalina.sh 的脚本中 , 追加如下配置

JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"

6-2 垃圾收集器

  1. 串⾏收集器(Serial Collector
单线程执⾏所有的垃圾回收⼯作, 适⽤于单核CPU服务器。

2. 并⾏收集器(Parallel Collector

⼜称为吞吐量收集器(关注吞吐量), 以并⾏的⽅式执⾏年轻代的垃圾回收, 该⽅式可以显著降 低垃圾回收的开销(指多条垃圾收集线程并⾏⼯作,但此时⽤户线程仍然处于等待状态)。适⽤于多 处理器或多线程硬件上运⾏的数据量较⼤的应⽤。

3. 并发收集器(Concurrent Collector

以并发的⽅式执⾏⼤部分垃圾回收⼯作,以缩短垃圾回收的暂停时间。适⽤于那些响应时间优先于 吞吐量的应⽤, 因为该收集器虽然最⼩化了暂停时间(指⽤户线程与垃圾收集线程同时执⾏,但不⼀ 定是并⾏的,可能会交替进⾏), 但是会降低应⽤程序的性能。

4. CMS 收集器(Concurrent Mark Sweep Collector

并发标记清除收集器, 适⽤于那些更愿意缩短垃圾回收暂停时间并且负担的起与垃圾回收共享处 理器资源的应⽤

5. G1 收集器(Garbage-First Garbage Collector

适⽤于⼤容量内存的多核服务器, 可以在满⾜垃圾回收暂停时间⽬标的同时, 以最⼤可能性实现 ⾼吞吐量(JDK1.7 之后)

垃圾回收器参数

参数描述
-XX:+UseSerialGC启⽤串⾏收集器
-XX:+UseParallelGC启⽤并⾏垃圾收集器,配置了该选项,那么 -XX:+UseParallelOldGC默认启⽤
-XX:+UseParNewGC年轻代采⽤并⾏收集器,如果设置了 -XX:+UseConcMarkSweepGC选项,⾃动启⽤
-XX:ParallelGCThreads年轻代及⽼年代垃圾回收使⽤的线程数。默认值依赖于JVM使⽤的CPU个数
-XX:+UseConcMarkSweepGC对于⽼年代,启⽤CMS垃圾收集器。 当并⾏收集器⽆法满⾜应⽤的延迟需求时,
推荐使⽤CMS或G1收集器。启⽤该选项后,-XX:+UseParNewGC⾃动启⽤。
-XX:+UseG1GC启⽤G1收集器。 G1是服务器类型的收集器, ⽤于多核、⼤内存的机器。
它在保持⾼吞吐量的情况下,⾼概率满⾜GC暂停时间的⽬标。
bin/catalina.sh 的脚本中 , 追加如下配置:

sh JAVA_OPTS="-XX:+UseConcMarkSweepGC"

如果存在虚拟机内存相关参数配置,则直接在 JAVA_OPTS 中追加即可。

6-3 Tomcat 配置调优

  1. 启用 Tomcat 线程池
  2. 调整 Tomcat 的连接器
调整 Tomcat/conf/server.xml 中关于链接器的配置可以提升应⽤服务器的性能。

参数说明
maxConnections最⼤连接数,当到达该值后,服务器接收但不会处理更多的请求, 额外的请求将会阻塞直到连接数低于maxConnections 。可通过ulimit -a 查看服务器限制。对于CPU要求更⾼(计算密集型)时,建议不要配置过⼤ ; 对于CPU要求不是特别⾼时,建议配置在2000左右(受服务器性能影响)。 当然这个需要服务器硬件的⽀持
maxThreads最⼤线程数,需要根据服务器的硬件情况,进⾏⼀个合理的设置
acceptCount最⼤排队等待数,当服务器接收的请求数量到达maxConnections ,此时Tomcat会将后⾯的请求,存放在任务队列中进⾏排序, acceptCount指的就是任务队列中排队等待的请求数 。 ⼀台Tomcat的最⼤的请求处理数量,是maxConnections + acceptCount
3. 禁⽤ AJP 连接器




4. 调整 IO 模式

Tomcat8 之前的版本默认使⽤ BIO(阻塞式 IO),对于每⼀个请求都要创建⼀个线程来处理,不适合⾼并发;Tomcat8 以后的版本默认使⽤ NIO 模式(⾮阻塞式 IO)。




Tomcat 并发性能有较⾼要求或者出现瓶颈时,我们可以尝试使⽤ APR 模式,APRApache Portable Runtime)是从操作系统级别解决异步 IO 问题,使⽤时需要在操作系统上安装 APRNative(因为 APR 原理是使⽤使⽤ JNI 技术调⽤操作系统底层的 IO 接⼝)。

5. 动静分离

可以使⽤ Nginx + Tomcat 相结合的部署⽅案,Nginx 负责静态资源访问,Tomcat 负责 Jsp 等动态资 源访问处理(因为 Tomcat 不擅⻓处理静态资源)。

源码

源码下载

关键词:知识,程序,须知

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭