目录
一、Tomcat概述
1、Tomcat定义
Tomcat 是由 Apache 软件基金会的 Jakarta 项目开发的一款开源的、免费的 Web 应用服务器,主要用于运行 Java Servlet 和 JSP(Java Server Pages)应用。
Tomcat 作为一个轻量级的应用服务器,广泛应用于中小型系统,尤其是在并发访问量不大的场合。尽管 Tomcat 能处理 HTML 页面,但其处理静态 HTML 的能力不及专门的 Web 服务器如 Apache 或 Nginx,因此 Tomcat 通常在后端作为 Servlet 和 JSP 容器运行。
2、Tomcat 的核心组件
Web 容器:
- 负责完成 Web 服务器的功能,主要用于管理和处理 HTTP(S) 请求。Web 容器封装了一组可以通过 HTTP(S) 协议访问的文件,包括静态页面和动态内容。它的作用类似于 Nginx 和 Apache,但更侧重于处理 Java Web 应用的环境。
- Web 容器允许集中化管理这些 Web 资源,并处理动态页面(如 JSP)。
Servlet 容器:
- Catalina 是 Tomcat 的核心 Servlet 容器,用于处理和管理 Servlet 代码。Servlet 是运行在服务器端的小型 Java 程序,能够动态生成 Web 页面。
- Servlet 容器负责加载、初始化、执行 Servlet,并处理 Servlet 和客户端之间的通信。
JSP 容器:
- JSP 容器用于将 JSP 页面翻译成 Servlet 代码。JSP 是一种用于开发动态 Web 内容的技术,允许嵌入 Java 代码到 HTML 页面中。
- JSP 页面被翻译成 Servlet 后,Servlet 容器会执行这些 Servlet,生成最终的动态内容并返回给客户端。
3、Tomcat 功能组件结构
Tomcat 作为一款轻量级的 Java Web 应用服务器,其核心功能组件包括 Connector(连接器)和 Container(容器)。这两个组件相辅相成,共同构成了 Tomcat 的基本 Web 服务 Service。每个 Tomcat 服务器可以管理多个 Service,各 Service 之间相互独立。
-
Connector:Tomcat 的 Connector 是连接外界和服务器的桥梁,负责监听端口接收客户端请求,并将请求转发给内部的 Container 进行处理,最终将处理结果返回给客户端。
-
Container:Container 是 Tomcat 的核心处理单元,负责执行业务逻辑。它通过多个层次的子容器管理和调用 Servlet,以解析并处理来自 Connector 的请求。
-
Service:Service 是 Tomcat 提供的完整 Web 服务,集成了 Connector 和 Container。每个 Tomcat 实例可以管理多个 Service,各自独立地处理和响应不同的客户端请求。
4、Tomcat Container 结构分析
在 Tomcat 的架构中,每个 Service 都包含一个核心容器——Container。Container 内部由四个子容器组成,分别是 Engine、Host、Context 和 Wrapper,它们彼此之间形成了层级结构。
-
Engine(引擎):引擎是 Container 的顶层子容器,用于管理多个虚拟主机。每个 Service 只能包含一个 Engine,负责在其下管理所有的虚拟主机(Host)。
-
Host(虚拟主机/站点):Host 代表一个虚拟主机或站点,通过配置 Host,可以在同一台物理服务器上运行多个站点。每个 Host 容器可以管理多个 Web 应用(Context)。
-
Context(Web 应用):Context 代表一个具体的 Web 应用程序。它是 Host 下的子容器,负责管理和组织该 Web 应用中的所有 Servlet 和资源。
-
Wrapper(封装器):Wrapper 是 Container 中的最底层子容器,负责封装单个 Servlet。每个 Wrapper 仅封装一个 Servlet,管理其生命周期,包括实例的创建、执行以及销毁。
Engine、Host、Context 和 Wrapper,这四个容器之间属于父子关系。
容器 由一个引擎可以管理多个虚拟主机。每个虚拟主机可以管理多个 Web 应用。每个 Web 应用会有多个 Servlet 封装器。
二、Tomcat 请求处理过程
1、接收请求
当用户在浏览器中输入一个网址并发出请求时,该请求被发送到服务器的 8080 端口。这个端口通常是 Tomcat 服务器的默认端口,负责处理 HTTP 请求。
在该端口上,Tomcat 的 Connector 组件一直在监听请求。Connector 作为 Tomcat 的“门卫”,负责接收所有进入服务器的网络请求。
2、解析并传递请求
Connector 捕获到请求后,会首先解析 HTTP 请求信息,如请求的 URL、请求方法(GET、POST 等)以及请求头信息等。
解析完成后,Connector 将该请求对象(Request)交给它所在的 Service 组件的核心处理单元——Engine 容器(Container)。此时,Connector 会等待 Engine 处理请求并返回响应。
3、容器链处理请求
Engine 是 Tomcat 的最高级别容器,它负责管理下级的 Host 容器,并根据请求的域名选择合适的 Host 容器进行进一步处理。
Host 代表一个虚拟主机或站点,负责管理多个 Context 容器(即具体的 Web 应用)。根据请求的路径,Host 容器会选择对应的 Context 进行处理。
Context 是 Web 应用的容器,它管理和组织该应用中的所有 Servlet 和资源。根据请求的路径和映射规则,Context 会选择合适的 Wrapper 容器。
Wrapper 是最底层的容器,每个 Wrapper 封装一个具体的 Servlet 实例。最终,Wrapper 将请求传递给对应的 Servlet,在其中执行与该请求相关的业务逻辑,如数据处理、数据库操作等。
4、执行业务逻辑
在 Servlet 中,程序会根据请求的具体内容(如请求参数)执行相应的业务逻辑。这可能包括查询数据库、处理表单数据、调用其他服务等操作。
处理完成后,Servlet 会生成一个响应对象(Response),其中包含将要返回给客户端的数据,如生成的 HTML 页面、JSON 数据等。
5、返回响应
生成响应后,Servlet 会将该响应对象交回给 Wrapper 容器。
响应对象会沿着请求路径的逆向,逐层返回:从 Wrapper 返回到 Context,再从 Context 返回到 Host,最后回到 Engine。
Engine 容器最终将响应对象传递给 Connector,完成业务处理。
Connector 收到响应对象后,会将其转换成标准的 HTTP 响应格式,通过网络将响应数据返回给发出请求的客户端(用户浏览器)。
三、Tomcat安装部署
- tomcat官网网站下载:https://tomcat.apache.org/download-90.cgi
- JDK官方下载:https://www.oracle.com/java/technologies/downloads/#java22
- 在部署 Tomcat 之前必须安装好 jdk,因为 jdk 是 Tomcat 运行的必要环境。
1、关闭防火墙和临时防护
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2、安装 JDK
cd /opt
rpm -qpl jdk-8u201-linux-x64.rpm
rpm -ivh jdk-8u201-linux-x64.rpm
java -version
3、配置 JDK 环境变量
编辑 /etc/profile.d/java.sh
文件
vim /etc/profile.d/java.sh
添加以下内容:
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATH
使环境变量生效:
source /etc/profile.d/java.sh
java -version
4、编写和运行 Java 程序示例
编写 Hello.java
[root@localhost opt]# vim Hello.java
public class Hello {
public static void main(String[] args){
System.out.println("Hello world!");
}
}
编译和运行 Java 程序
javac Hello.java
java Hello
5、安装和启动 Tomcat
解压 Tomcat 并移动到 /usr/local
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mv apache-tomcat-9.0.16 /usr/local/tomcat
启动 Tomcat
- 后台启动
/usr/local/tomcat/bin/startup.sh
- 前台启动
/usr/local/tomcat/bin/catalina.sh run
检查 Tomcat 是否在运行
netstat -natp | grep 8080
访问 Tomcat 默认主页: 浏览器访问:http://172.16.88.11:8080
6、配置 Tomcat 为系统服务
创建 Tomcat 用户
useradd -s /sbin/nologin tomcat
修改 Tomcat 目录权限
chown tomcat:tomcat /usr/local/tomcat -R
创建 Tomcat 服务文件
cat > /usr/lib/systemd/system/tomcat.service <<EOF
[Unit]
Description=Tomcat
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
EOF
重新加载系统服务并启动 Tomcat
systemctl daemon-reload
systemctl start tomcat
检查 Tomcat 服务是否启动
ss -ntap | grep 8080
7、优化 Tomcat 启动速度
在第一次启动 Tomcat 时,可能会发现启动速度很慢,默认情况下可能需要几十秒。可以通过修改 JDK 的配置文件来加快启动速度。
修改 java.security
文件
vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
在文件中找到第 117 行,将 securerandom.source
的值修改为
securerandom.source=file:/dev/urandom
解释:
/dev/urandom
是/dev/random
的非阻塞版本。/dev/random
依赖系统中断,因此在系统中断不足时会阻塞,导致进程等待。而/dev/urandom
不依赖系统中断,不会阻塞进程,但随机性较低。如果应用对安全性要求较高,应使用/dev/random
。
重启 Tomcat
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
8、Tomcat 主要目录说明
ll /usr/local/tomcat/
/bin
:存放启动和关闭 Tomcat 的脚本文件,常用文件包括:
catalina.sh
startup.sh
shutdown.sh
/conf
:存放 Tomcat 服务器的各种配置文件,常用文件包括:
server.xml
:Tomcat 的主配置文件,包含 Service、Connector、Engine、Realm、Valve、Hosts 组件的相关配置信息。context.xml
:所有 host 的默认配置信息。tomcat-users.xml
:存放 Realm 认证所用的角色、用户和密码信息。Tomcat 自带的 manager 会用到此文件,添加/删除用户和指定角色可通过编辑此文件实现。web.xml
:遵循 Servlet 规范标准的配置文件,用于配置 servlet,并为所有的 Web 应用程序提供包括 MIME 映射等默认配置信息。-
/lib
:存放 Tomcat 运行所需的库文件的 JAR 包,一般不作改动。连接第三方服务(如 Redis)时,需添加对应的 JAR 包。 -
/logs
:存放 Tomcat 执行时的日志文件。 -
/temp
:存放 Tomcat 运行时产生的临时文件。 -
/webapps
:存放 Tomcat 默认的 Web 应用部署目录。 -
/work
:存放 Tomcat 的工作目录,主要存放 JSP 编译后生成的 class 文件。清除 Tomcat 缓存时会使用到此目录。 -
/src
:存放 Tomcat 的源代码。 -
/doc
:存放 Tomcat 文档。
四、Tomcat 虚拟主机配置
当需要在同一台服务器上运行多个 Tomcat 项目时,可以使用 Tomcat 的虚拟主机功能来管理多个域名访问不同的项目内容。
1、创建项目目录和文件
mkdir /usr/local/tomcat/webapps/kgc
mkdir /usr/local/tomcat/webapps/benet
echo "This is kgc page!" > /usr/local/tomcat/webapps/kgc/index.jsp
echo "This is benet page!" > /usr/local/tomcat/webapps/benet/index.jsp
2、修改 Tomcat 主配置文件 server.xml
编辑 server.xml
文件
vim /usr/local/tomcat/conf/server.xml
在文件中的 <Engine>
标签内的适当位置(通常是第 165 行前)插入以下配置
<Host name="www.kgc.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/kgc" path="" reloadable="true" />
</Host>
<Host name="www.benet.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/benet" path="" reloadable="true" />
</Host>
解释配置参数:
appBase
:Tomcat 应用程序工作目录,用于存放 web 应用程序的目录。相对路径为webapps
,绝对路径为/usr/local/tomcat/webapps
。unpackWARs
:是否在启动时对 WAR 格式的归档文件进行展开。默认为true
。autoDeploy
:是否在 Tomcat 运行时自动部署appBase
目录中的应用程序。默认为true
。xmlValidation
:是否验证 XML 文件的有效性。默认为false
。xmlNamespaceAware
:是否启用 XML 命名空间。与xmlValidation
一起设置为true
时,对web.xml
文件进行有效性检验。docBase
:Web 应用程序的存放位置,可以使用绝对路径或相对于appBase
的路径。path
:相对于 Web 服务器根路径的 URI。如果为空(""
),则表示 Web 应用的根路径/
。reloadable
:是否允许重新加载此 Context 相关的 Web 应用程序的类。默认为false
。
3、启动 Tomcat 服务
/usr/local/tomcat/bin/shutdown.sh //关闭 Tomcat
/usr/local/tomcat/bin/startup.sh //启动 Tomcat
4、客户端浏览器访问验证
更新 /etc/hosts
文件
echo "192.168.10.23 www.kgc.com www.benet.com" >> /etc/hosts
在浏览器中访问以下地址:
- 访问 http://www.kgc.com:8080/ 页面应显示 "This is kgc page!"
- 访问 http://www.benet.com:8080/ 页面应显示 "This is benet page!"
五、Tomcat 优化
为了提高 Tomcat 在生产环境中的性能和稳定性,需要对其进行详细的优化。这些优化通常包括操作系统(内核参数)优化、Tomcat 配置文件参数优化以及 Java 虚拟机(JVM)调优。
1、Tomcat 配置文件参数优化
在 Tomcat 的 server.xml
配置文件中,可以调整以下参数来优化 Tomcat 的性能
-
redirectPort
:当连接器接收到 HTTPS 请求时,将请求重定向到此端口。 -
maxThreads
:指定 Tomcat 可创建的最大线程数,即支持的最大并发连接数。默认值是 200。增加此值可以提高并发处理能力,但也会增加内存消耗。 -
minSpareThreads
:Tomcat 启动时的最小空闲线程数。即使没有请求也会启动这些线程。默认值是 10。适当增加可以减少请求到达时的线程创建延迟。 -
maxSpareThreads
:最大备用线程数,超过此值的线程会被关闭。默认值是 -1(无限制)。通常不需要修改。 -
URIEncoding
:指定 Tomcat 的 URL 编码格式。通常设置为UTF-8
。 -
connectionTimeout
:网络连接超时的时间(单位:毫秒)。设置为 0 表示永不超时。通常设置为 20000 毫秒(20 秒)。 -
enableLookups
:是否进行反向 DNS 查找以获取主机名。设置为false
可以提高处理性能,避免 DNS 查找延迟。 -
disableUploadTimeout
:是否对上传使用超时机制。应设置为true
以避免上传过程中的超时问题。 -
connectionUploadTimeout
:上传超时时间,应与disableUploadTimeout
配合使用。 -
acceptCount
:当所有处理请求的线程都在使用时,允许排队等待处理的最大请求数。默认值是 100。适当增加可以避免请求被拒绝(如 502 错误)。 -
compression
:是否对响应数据进行 GZIP 压缩。设置为on
可以减少页面大小,节省带宽。 -
compressionMinSize
:响应报文的最小大小,只有当响应报文大于此值时才进行压缩。默认值是 2048 字节(2 KB)。 -
compressableMimeType
:指定需要压缩的 MIME 类型,如text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png
。 -
noCompressionUserAgents
:指定不启用压缩的用户代理(浏览器),如gozilla, traviata
。
2、配置文件
编辑 server.xml
文件,调整配置如下
vim /usr/local/tomcat/conf/server.xml
在 <Connector>
标签中添加或修改以下配置
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
minSpareThreads="50"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="300"
maxThreads="500"
URIEncoding="UTF-8"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpeg,image/png"/>
六、Tomcat 多实例部署
1、安装 JDK
确保已经安装好 JDK,并配置好环境变量。
2、安装 Tomcat
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mkdir /usr/local/tomcat
mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1
cp -a /usr/local/tomcat/tomcat1 /usr/local/tomcat/tomcat2
3、配置 Tomcat 环境变量
创建环境变量配置文件
vim /etc/profile.d/tomcat.sh
# Tomcat 1
export CATALINA_HOME1=/usr/local/tomcat/tomcat1
export CATALINA_BASE1=/usr/local/tomcat/tomcat1
export TOMCAT_HOME1=/usr/local/tomcat/tomcat1
# Tomcat 2
export CATALINA_HOME2=/usr/local/tomcat/tomcat2
export CATALINA_BASE2=/usr/local/tomcat/tomcat2
export TOMCAT_HOME2=/usr/local/tomcat/tomcat2
使环境变量生效
source /etc/profile.d/tomcat.sh
4、修改 Tomcat 实例配置文件
Tomcat 1 配置文件(默认端口不需修改)
Tomcat 2 配置文件:
修改 server.xml
文件中的端口设置
vim /usr/local/tomcat/tomcat2/conf/server.xml
将以下端口号修改为不同于 Tomcat 1 的端口
<Server port="8006" shutdown="SHUTDOWN"> <!-- 修改 Server port -->
<!-- 其他配置 -->
</Server>
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" /> <!-- 修改 HTTP 连接器端口 -->
<Connector port="8010" protocol="AJP/1.3"
redirectPort="8443" /> <!-- 修改 AJP 连接器端口 -->
5、修改启动和关闭脚本
Tomcat 1 启动和关闭脚本
编辑 startup.sh
和 shutdown.sh
文件,设置环境变量
vim /usr/local/tomcat/tomcat1/bin/startup.sh
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
编辑 shutdown.sh
文件
vim /usr/local/tomcat/tomcat1/bin/shutdown.sh
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
Tomcat 2 启动和关闭脚本
编辑 startup.sh
和 shutdown.sh
文件,设置环境变量
vim /usr/local/tomcat/tomcat2/bin/startup.sh
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
编辑 shutdown.sh
文件
vim /usr/local/tomcat/tomcat2/bin/shutdown.sh
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
6、启动 Tomcat 实例
启动各 Tomcat 实例
/usr/local/tomcat/tomcat1/bin/startup.sh
/usr/local/tomcat/tomcat2/bin/startup.sh
使用 netstat
命令检查端口是否正确
netstat -natp | grep java
浏览器访问测试
通过浏览器访问以下 URL 进行测试:
七、JVM 扩展优化
1、JVM Server 工作模式
-server
启动 JVM 的 server 工作模式,适用于长期运行的服务器应用程序。另一个模式是 client 工作模式,主要用于桌面应用程序。使用 java -version
命令可以查看当前工作模式。
2、初始 Heap 大小和最大 Heap 大小
-Xms1024m
-Xmx1024m
-Xms1024m
:设置 JVM 启动时分配的初始内存大小(Heap)。设置为 1024 MB。-Xmx1024m
:设置 JVM 最大可以使用的内存大小(Heap)。设置为 1024 MB。经验法则是将-Xms
和-Xmx
设置为相同的值,以避免内存调整的开销。
3、新生代内存设置
-XX:NewSize=512m
-XX:MaxNewSize=1024m
-XX:NewSize=512m
:设置新生代(Young Generation)初始内存大小。应该小于-Xms
的值。-XX:MaxNewSize=1024m
:设置新生代最大内存上限。应该小于-Xmx
的值。
4、永久代内存设置
-XX:PermSize=1024m
-XX:MaxPermSize=1024m
-XX:PermSize=1024m
:设置永久代(Permanent Generation)内存的初始大小。永久代用于存放 Class 和 Meta 信息,该区域在 JVM 运行期间不会被清除。-XX:MaxPermSize=1024m
:设置永久代内存的最大大小。经验法则是将-XX:PermSize
和-XX:MaxPermSize
设置为相同的值。
5、禁用显式垃圾回收
-XX:+DisableExplicitGC
该选项自动将 System.gc()
调用转换为空操作。即使应用程序中调用了 System.gc()
,也不会触发垃圾回收。这可以防止应用程序在不必要的情况下触发垃圾回收,通常建议将垃圾回收的控制交给 JVM。