一、Tomcat 基础认知:先搞懂 “它是什么、跟谁搭”
在学操作前,必须先明确 Tomcat 的定位 —— 它是Java Web 应用的 “运行容器”(好比 “手机是 APP 的运行容器”),本质是解析 Java 代码(JSP/Servlet)、处理 HTTP 请求的服务器。运维的核心目标是:让 Tomcat 稳定跑起来、能部署应用、出问题能快速解决。
1.1 Tomcat 与 Java 的 “强绑定” 关系(必懂!)
Tomcat 依赖JDK(Java 开发工具包) 才能运行(好比 “手机 APP 依赖操作系统”),二者版本必须匹配,否则会报错。
低版本 Tomcat(如 Tomcat 7)支持 JDK 1.6/1.7;主流版本(Tomcat 8.5/9)支持 JDK 1.8 及以上;高版本(Tomcat 10)支持 JDK 11 及以上(注意:Tomcat 10 对 Java 包名做了调整,部分老应用可能不兼容,运维选 8.5/9 更稳妥)。
1.2 Tomcat 的核心作用(运维视角)
接收用户的 HTTP 请求(比如用户访问 “www.xxx.com”);把请求转发给 Web 应用(比如部署在 Tomcat 里的 “电商系统”);接收应用的处理结果,再返回给用户;管理应用的生命周期(启动 / 停止 / 重启应用)。
1.3 Tomcat 的版本选择(工作避坑点)
生产环境优先选稳定版(带 “xx.x.x”,如 Tomcat 8.5.93、9.0.80),避免选 “alpha/beta” 测试版;下载渠道:官网(Apache Tomcat),选 “Core” 下的 “tar.gz” 包(Linux 系统专用格式),不要下 Windows 的 “zip” 包。
二、环境准备:Linux+JDK(Tomcat 的 “地基”)
运维所有操作都在 Linux 上,先搭好基础环境 ——Linux 系统(推荐 CentOS 7/8 或 Ubuntu 20.04)+ JDK,步骤必须严谨,否则后续 Tomcat 启动会报错。
2.1 Linux 系统基础(运维必备,不赘述但要会)
至少掌握:
常用命令:(切换目录)、
cd(看文件)、
ls(建目录)、
mkdir(解压)、
tar(编辑文件)、
vi(管理服务)、
systemctl(查端口)、
netstat/ss(查进程);权限管理:
ps(改文件权限)、
chmod(改文件所有者)(后续 Tomcat 不能用 root 跑,必须改权限)。
chown
2.2 JDK 安装与配置(关键步骤,附命令)
步骤 1:下载 JDK(以 JDK 1.8 为例)
官网下载(Oracle JDK),注意选 “Linux x64 Compressed Archive”(tar.gz 包);也可以用 Linux 命令直接下载(需先装):
wget
bash
wget https://download.oracle.com/otn-pub/java/jdk/8u391-b13/7c87d62e-32e1-477c-918c-151421c3ed61/jdk-8u391-linux-x64.tar.gz
步骤 2:解压 JDK 到指定目录(运维习惯放
/usr/local/)
/usr/local/
bash
# 建目录
mkdir -p /usr/local/java
# 解压到目录
tar -zxvf jdk-8u391-linux-x64.tar.gz -C /usr/local/java/
# 重命名(方便后续配置,可选)
mv /usr/local/java/jdk1.8.0_391 /usr/local/java/jdk8
步骤 3:配置 JDK 环境变量(全局生效,改
/etc/profile)
/etc/profile
bash
# 编辑profile文件
vi /etc/profile
# 在文件末尾添加以下内容(指定JDK路径)
export JAVA_HOME=/usr/local/java/jdk8
export JRE_HOME=$JAVA_HOME/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
# 让配置生效
source /etc/profile
步骤 4:验证 JDK 是否安装成功
bash
# 查看Java版本,出现“1.8.0_391”说明成功
java -version
# 查看javac命令(编译Java的工具),出现用法说明说明成功
javac -version
三、Tomcat 安装与基础操作(运维入门第一步)
这部分是 “上手实操”,重点掌握 “安装→启停→目录理解”,后续所有配置都基于这些基础。
3.1 Tomcat 安装(以 Tomcat 8.5 为例)
步骤 1:下载 Tomcat(官网或命令下载)
bash
# 进入/usr/local/目录(习惯放这里)
cd /usr/local/
# 下载Tomcat 8.5.93(官网复制的最新稳定版链接,可替换)
wget https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.93/bin/apache-tomcat-8.5.93.tar.gz
步骤 2:解压 Tomcat(简单,tar 命令搞定)
bash
tar -zxvf apache-tomcat-8.5.93.tar.gz
# 重命名(简化目录名,方便后续操作)
mv apache-tomcat-8.5.93 tomcat8.5
步骤 3:改权限(运维必做!禁止用 root 跑 Tomcat)
Tomcat 用 root 运行有安全风险(比如应用被入侵后能拿到系统最高权限),必须创建专门用户(比如):
tomcat
bash
# 1. 创建tomcat用户(-m:建家目录,-s:指定shell)
useradd -m -s /bin/bash tomcat
# 2. 给tomcat用户设密码(输入两次密码,看不见输入是正常的)
passwd tomcat
# 3. 把Tomcat目录的所有权改给tomcat用户
chown -R tomcat:tomcat /usr/local/tomcat8.5/
# 4. 给bin目录下的脚本加执行权限(否则无法启停)
chmod +x /usr/local/tomcat8.5/bin/*.sh
3.2 Tomcat 目录结构详解(运维必须记熟!)
解压后的目录里有 7 个核心子目录,每个目录的作用直接关联后续配置 / 排查,用表格讲清楚:
tomcat8.5
| 目录名 | 核心作用 | 运维常用操作举例 |
|---|---|---|
| bin | 存放 Tomcat 启停脚本(启动、停止)、环境配置脚本 |
执行启动 Tomcat |
| conf | 存放 Tomcat 所有配置文件(核心!比如、) |
改调整端口、改设欢迎页 |
| webapps | 存放 Web 应用的目录(部署的 war 包 / 解压后的应用都放这) | 把包丢这里,Tomcat 会自动解压 |
| logs | 存放 Tomcat 所有日志(排查问题全靠它!) | 看查启动失败原因 |
| lib | 存放 Tomcat 依赖的 Java 库(jar 包),应用可共用这些库 | 很少手动改,除非需要加全局依赖 |
| work | Tomcat 的临时目录(解析 JSP 生成的 Java 文件、编译后的 class 文件) | 应用出 JSP 相关错误时,可删除这里重启 |
| temp | Tomcat 的临时文件目录(比如上传文件的临时存储) | 空间不足时可清理,不影响核心功能 |
3.3 Tomcat 基础启停操作(3 种方式,运维都要会)
方式 1:用 bin 目录的脚本启停(最基础,适合手动操作)
bash
# 1. 切换到tomcat用户(必须!之前改了权限,root启动会报错)
su - tomcat
# 2. 进入bin目录
cd /usr/local/tomcat8.5/bin/
# 3. 启动Tomcat(./表示当前目录)
./startup.sh
# 4. 验证是否启动成功(两种方法)
# 方法A:查进程(有“org.apache.catalina.startup.Bootstrap”说明成功)
ps -ef | grep tomcat
# 方法B:查端口(Tomcat默认HTTP端口是8080,出现“LISTEN”说明成功)
ss -tulpn | grep 8080
# 5. 停止Tomcat
./shutdown.sh
# 6. 强制停止(如果shutdown.sh停不掉,用kill命令)
kill -9 $(ps -ef | grep tomcat | grep -v grep | awk '{print $2}')
方式 2:配置成 Linux 系统服务(
systemctl管理,运维推荐)
systemctl
手动执行脚本麻烦,生产环境一般把 Tomcat 做成系统服务,用管理,步骤:
systemctl start/stop/restart
bash
# 1. 切换回root用户(配置服务需要root权限)
su - root
# 2. 创建服务配置文件(/etc/systemd/system/目录下,文件名自定义,比如tomcat8.5.service)
vi /etc/systemd/system/tomcat8.5.service
# 3. 写入以下内容(注意路径要和你的Tomcat目录一致!)
[Unit]
Description=Apache Tomcat 8.5
After=network.target # 网络启动后再启动Tomcat
[Service]
Type=forking # 后台运行模式
User=tomcat # 运行用户
Group=tomcat # 运行用户组
# 启动命令(指定CATALINA_HOME,即Tomcat目录)
ExecStart=/usr/local/tomcat8.5/bin/startup.sh
# 停止命令
ExecStop=/usr/local/tomcat8.5/bin/shutdown.sh
# 重启命令
ExecReload=/bin/kill -HUP $MAINPID
# 进程结束后,自动重启(可选,生产环境建议开)
Restart=on-failure
RestartSec=5 # 失败后5秒重启
[Install]
WantedBy=multi-user.target # 多用户模式下生效
# 4. 重新加载systemd配置(让新服务生效)
systemctl daemon-reload
# 5. 测试服务命令(后续就用这些命令管理)
systemctl start tomcat8.5 # 启动
systemctl stop tomcat8.5 # 停止
systemctl restart tomcat8.5 # 重启
systemctl status tomcat8.5 # 查看状态(active(running)说明成功)
systemctl enable tomcat8.5 # 设置开机自启(生产环境必开)
方式 3:验证 Tomcat 是否能访问(浏览器 / 命令行都可)
浏览器访问:输入(比如
http://Linux服务器IP:8080),出现 Tomcat 默认页面(有 “Apache Tomcat” 字样)说明成功;命令行访问(服务器没图形界面时用):
http://192.168.1.100:8080
bash
# 用curl命令访问,出现HTML内容说明成功
curl http://localhost:8080
访问失败排查:先查防火墙(CentOS 关闭防火墙:;Ubuntu:
systemctl stop firewalld),再查 Tomcat 状态(
ufw disable),最后看日志(
systemctl status tomcat8.5)。
cat /usr/local/tomcat8.5/logs/catalina.out
四、Tomcat 核心配置(运维进阶核心,工作中 80% 场景用这个)
这部分是 “重头戏”,掌握后能应对 90% 的日常运维需求(比如改端口、部署应用、设密码)。核心配置文件都在目录下,重点讲 3 个文件:
conf(主配置)、
server.xml(应用全局配置)、
web.xml(用户权限)。
tomcat-users.xml
4.1 主配置文件:
server.xml(Tomcat 的 “大脑”)
server.xml
定义了 Tomcat 的核心组件(比如端口、请求处理引擎、应用主机),所有 “全局级” 配置都改这里。用 “组件拆解” 的方式讲,更易懂:
server.xml
4.1.1 核心组件解析(附配置片段 + 解释)
打开文件(
conf/server.xml),重点看以下组件:
vi /usr/local/tomcat8.5/conf/server.xml
① Server 组件(最外层,代表整个 Tomcat)
xml
<Server port="8005" shutdown="SHUTDOWN">
<!-- 里面是Service、Engine等组件 -->
</Server>
:Tomcat 的 “关闭端口”(仅本地能用,发送 “SHUTDOWN” 命令就停止 Tomcat),一般不用改;
port="8005":关闭命令的关键字,改不改都行,安全起见可改个复杂的(比如
shutdown="SHUTDOWN")。
shutdown="MyTomcatShutdown123"
② Service 组件(关联 “连接器” 和 “引擎”,相当于 “桥梁”)
xml
<Service name="Catalina">
<!-- 里面是Connector(连接器)和Engine(引擎) -->
</Service>
:Service 的名字,默认即可,多个 Service 可改不同名(很少用)。
name="Catalina"
③ Connector 组件(最常用!处理 HTTP/AJP 请求,改端口、协议都在这里)
Tomcat 默认有 2 个 Connector(HTTP 和 AJP),重点看 HTTP 的:
xml
<!-- HTTP Connector(处理浏览器的HTTP请求) -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- AJP Connector(处理其他服务器的请求,比如Apache,不用可删掉) -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
运维常用配置项(改这些就够了):
| 配置项 | 作用说明 | 示例(优化后) |
|---|---|---|
|
HTTP 端口(默认 8080,生产环境一般改 80(HTTP 默认端口,浏览器可省略端口)) | |
|
协议类型(即可,高版本可改(NIO 模式,性能更好)) |
|
|
连接超时时间(毫秒,默认 20000=20 秒,超时断开连接,避免资源占用) | |
|
HTTPS 重定向端口(当请求需要 HTTPS 时,自动跳这个端口,后续配 HTTPS 会用到) | (HTTPS 默认端口) |
|
最大线程数(处理请求的线程上限,默认 200,高并发场景可改 500-1000) | |
|
最小空闲线程数(默认 10,保持一定空闲线程,避免请求来时创建线程耗时) | |
|
最大连接数(同时处理的请求数,默认 10000,根据服务器内存调整) | |
示例:优化后的 HTTP Connector 配置(生产环境常用):
xml
<Connector port="80"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="30000"
redirectPort="443"
maxThreads="500"
minSpareThreads="20"
maxConnections="20000"
URIEncoding="UTF-8" <!-- 解决URL中文乱码问题,必加! -->
enableLookups="false" <!-- 关闭DNS反向解析,提高性能 -->
compression="on" <!-- 开启Gzip压缩,减少传输流量 -->
compressionMinSize="2048" <!-- 大于2KB的内容才压缩 -->
compressableMimeType="text/html,text/xml,text/css,application/javascript" /> <!-- 压缩的文件类型 -->
④ Engine 组件(请求处理引擎,Tomcat 的 “核心处理器”)
xml
<Engine name="Catalina" defaultHost="localhost">
<!-- 里面是Host(主机)组件 -->
</Engine>
:和 Service 名字对应,默认即可;
name="Catalina":默认主机名(当请求没有指定主机时,用这个),一般改服务器的域名(比如
defaultHost="localhost")。
defaultHost="www.xxx.com"
⑤ Host 组件(虚拟主机,一个 Host 对应一个域名 / 应用)
xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- 里面是Context(应用上下文)组件 -->
</Host>
运维常用配置项:
| 配置项 | 作用说明 | 示例 |
|---|---|---|
|
主机名(域名),比如,访问这个域名就对应此 Host |
|
|
应用基础目录(默认,即目录下的应用归这个 Host 管理) |
|
|
是否自动解压 war 包(:丢 war 包到,自动解压;:不解压,直接运行 war 包) |
|
|
是否自动部署(:新增 / 修改应用时,Tomcat 自动加载,不用重启;:需手动重启) |
|
|
应用 XML 配置目录(可选,默认,比如,在这里放应用配置文件,比直接改 server.xml 灵活) |
|
示例:配置多虚拟主机(比如一个服务器跑两个应用:和
www.xxx.com):
blog.xxx.com
xml
<!-- 第一个Host:www.xxx.com(主应用) -->
<Host name="www.xxx.com" appBase="webapps/www"
unpackWARs="true" autoDeploy="true">
</Host>
<!-- 第二个Host:blog.xxx.com(博客应用) -->
<Host name="blog.xxx.com" appBase="webapps/blog"
unpackWARs="true" autoDeploy="true">
</Host>
配置后,需要在下建
webapps和
www目录,分别放对应应用的 war 包。
blog
⑥ Context 组件(应用上下文,指定应用的路径和目录)
Context 用来 “精准定位应用”,比如把目录下的应用,映射到
/usr/local/myapp路径下。有两种配置方式:
http://www.xxx.com/myapp
方式 1:在 Host 里配置(不推荐,改 server.xml 需重启 Tomcat)
xml
<Host name="www.xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
<!-- docBase:应用的实际目录;path:访问路径(/myapp表示访问http://www.xxx.com/myapp) -->
<Context docBase="/usr/local/myapp" path="/myapp" reloadable="false" />
</Host>
方式 2:在目录下建 XML 文件(推荐,不用重启 Tomcat)比如 Host 的
xmlBase是
xmlBase,在这个目录下建
conf/Catalina/www.xxx.com(文件名就是访问路径前缀),内容:
myapp.xml
xml
<Context docBase="/usr/local/myapp" reloadable="false" />
访问路径:(文件名
http://www.xxx.com/myapp对应路径
myapp.xml);
/myapp:是否自动重新加载应用(
reloadable="false":应用文件改了自动加载,开发环境用;
true:生产环境用,避免频繁加载耗资源)。
false
4.2 全局应用配置:
web.xml(所有应用共用的配置)
web.xml
是 Tomcat 的全局 Web 应用配置文件,所有部署在 Tomcat 里的应用都会继承这里的配置,常用配置:
conf/web.xml
4.2.1 配置欢迎页(访问应用根路径时,默认打开的页面)
默认欢迎页是、
index.html、
index.htm,如果应用的欢迎页是
index.jsp,可在这里改:
home.html
xml
<welcome-file-list>
<welcome-file>home.html</welcome-file> <!-- 新增自定义欢迎页 -->
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
4.2.2 配置错误页面(应用报错时,显示自定义页面,比如 404、500)
默认报错会显示 Tomcat 的错误页,不友好,可自定义:
xml
<!-- 404错误:页面不存在 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.html</location> <!-- 自定义404页面路径 -->
</error-page>
<!-- 500错误:应用代码报错 -->
<error-page>
<error-code>500</error-code>
<location>/error/500.html</location>
</error-page>
<!-- 特定异常:比如Java的空指针异常 -->
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error/nullpointer.html</location>
</error-page>
需要在应用的根目录下建目录,放
error等页面。
404.html
4.2.3 配置 MIME 类型(解决浏览器下载文件而非预览的问题)
MIME 类型是 “文件类型与浏览器处理方式的映射”,比如对应 HTML 页面,
text/html对应 JPG 图片。如果浏览器访问
image/jpeg时直接下载而非预览,可能是 MIME 类型没配置:
xxx.pdf
xml
<mime-mapping>
<extension>pdf</extension> <!-- 文件后缀 -->
<mime-type>application/pdf</mime-type> <!-- 对应的MIME类型 -->
</mime-mapping>
<mime-mapping>
<extension>docx</extension>
<mime-type>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mime-type>
</mime-mapping>
4.3 用户权限配置:
tomcat-users.xml(管理 Tomcat 后台)
tomcat-users.xml
Tomcat 有两个管理后台(和
Manager App),用来图形化部署应用、管理主机,默认没有用户,需要在
Host Manager里配置用户和权限:
conf/tomcat-users.xml
配置步骤(附完整示例)
打开,在
conf/tomcat-users.xml标签里加用户:
<tomcat-users>
xml
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<!-- 1. 定义角色(权限):Tomcat预定义了4个核心角色 -->
<!-- manager-gui:访问Manager App后台的权限(图形界面) -->
<!-- manager-script:用脚本(比如curl)管理应用的权限 -->
<!-- host-manager-gui:访问Host Manager后台的权限 -->
<!-- admin-gui:(老版本)管理后台权限,新版本用manager-gui/host-manager-gui -->
<role rolename="manager-gui"/>
<role rolename="host-manager-gui"/>
<!-- 2. 创建用户:username(用户名)、password(密码)、roles(关联的角色) -->
<user username="tomcatadmin" password="Tomcat@123456" roles="manager-gui,host-manager-gui"/>
</tomcat-users>
允许远程访问管理后台(默认仅本地能访问)
默认情况下,只能在 Linux 服务器本地访问管理后台(),远程浏览器访问会报 403,需要改 IP 限制:
http://localhost:8080/manager/html
改 Manager App 的 IP 限制:找到
vi /usr/local/tomcat8.5/webapps/manager/META-INF/context.xml标签,把
<Valve>改成你的 IP(比如
allow允许内网访问,
192.168.1.*允许所有 IP,生产环境不推荐
0.0.0.0/0):
0.0.0.0/0
xml
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1|192.168.1.*" />
改 Host Manager 的 IP 限制:同上,修改
vi /usr/local/tomcat8.5/webapps/host-manager/META-INF/context.xml的值。重启 Tomcat:
allow,之后远程浏览器访问
systemctl restart tomcat8.5,输入用户名
http://服务器IP:8080/manager/html和密码
tomcatadmin即可登录。
Tomcat@123456
五、Web 应用部署(运维核心工作:把代码跑起来)
部署应用是运维的日常工作,Tomcat 支持 4 种部署方式,从简单到复杂都要会。
5.1 方式 1:webapps 目录自动部署(最简单,适合新手 / 测试环境)
原理:Tomcat 的目录(默认
appBase)会自动监控文件变化,把 war 包丢进去就自动部署。步骤:
webapps
把开发给的包(比如
xxx.war)上传到
myapp.war目录(或 Host 对应的
webapps目录,比如
appBase):
webapps/www
bash
# 上传文件(用scp命令从本地传到服务器,本地执行)
scp C:myapp.war tomcat@192.168.1.100:/usr/local/tomcat8.5/webapps/
# 或在服务器上直接下载war包
wget https://xxx.com/myapp.war -P /usr/local/tomcat8.5/webapps/
等待 1-2 秒,Tomcat 会自动解压成
myapp.war目录;访问应用:
myapp(比如
http://服务器IP:端口/myapp);更新应用:直接替换
http://192.168.1.100:8080/myapp里的
webapps包,Tomcat 会自动重新解压(
myapp.war时);删除应用:删除
autoDeploy="true"里的
webapps和
myapp.war目录,Tomcat 会自动卸载。
myapp
5.2 方式 2:Manager App 后台部署(图形化,适合临时部署 / 非 root 用户)
原理:通过 Tomcat 的管理后台()上传 war 包,不用操作命令行,适合运维没服务器 root 权限的场景。步骤:
/manager/html
浏览器访问,登录(之前配置的
http://服务器IP:8080/manager/html用户);找到 “Deploy” 模块,选择 “WAR file to deploy”;点击 “Browse” 选择本地的
tomcatadmin包,点击 “Deploy”;部署成功后,在 “Applications” 列表里会看到
myapp.war,点击路径即可访问;更新 / 删除应用:在 “Applications” 列表里,点击
/myapp对应的 “Reload”(更新)或 “Undeploy”(删除)。
/myapp
5.3 方式 3:Context XML 配置部署(灵活,适合生产环境)
原理:在目录(比如
xmlBase)下建 XML 文件,指定应用的实际路径,优点是 “应用目录可放任意位置,不用丢 webapps”,且改配置不用重启 Tomcat(
conf/Catalina/www.xxx.com时)。步骤:
autoDeploy="true"
把解压后的目录(不是 war 包)放到自定义路径,比如
myapp:
/data/apps/myapp
bash
# 建目录
mkdir -p /data/apps/
# 解压war包到该目录(如果是war包的话)
unzip /usr/local/myapp.war -d /data/apps/myapp/
# 改权限(必须让tomcat用户有权访问)
chown -R tomcat:tomcat /data/apps/myapp/
进入 Host 对应的目录(比如
xmlBase的
www.xxx.com是
xmlBase,没有就建):
conf/Catalina/www.xxx.com
bash
mkdir -p /usr/local/tomcat8.5/conf/Catalina/www.xxx.com/
在该目录下建文件(文件名对应访问路径
myapp.xml):
/myapp
xml
<Context docBase="/data/apps/myapp" <!-- 应用实际目录 -->
reloadable="false" <!-- 生产环境关自动重载 -->
allowLinking="true" <!-- 允许符号链接(可选) -->
cachingAllowed="true" <!-- 开启缓存(可选,提高性能) -->
cacheMaxSize="10240" /> <!-- 缓存最大10MB(可选) -->
不用重启 Tomcat(会自动加载),访问应用:
autoDeploy="true";更新应用:直接替换
http://www.xxx.com/myapp目录下的文件,然后在 Manager 后台点击 “Reload”(或删除
/data/apps/myapp再重建,触发重新加载)。
myapp.xml
5.4 方式 4:命令行部署(适合脚本自动化 / 生产环境批量部署)
原理:用 Tomcat 的角色权限,通过命令行(
manager-script或
curl)调用管理接口部署应用,适合写脚本批量操作。步骤:
wget
先在里配置一个有
tomcat-users.xml角色的用户(用于命令行认证):
manager-script
xml
<role rolename="manager-script"/>
<user username="tomcatscript" password="Script@123" roles="manager-script"/>
重启 Tomcat:;命令行部署 war 包(本地或服务器上执行):
systemctl restart tomcat8.5
bash
# 格式:curl -u 用户名:密码 -T war包路径 "http://服务器IP:端口/manager/text/deploy?path=/应用路径&update=true"
# -u:指定用户名密码;-T:上传文件;update=true:如果应用已存在,更新它
curl -u tomcatscript:Script@123 -T /usr/local/myapp.war "http://192.168.1.100:8080/manager/text/deploy?path=/myapp&update=true"
命令行卸载应用:
bash
curl -u tomcatscript:Script@123 "http://192.168.1.100:8080/manager/text/undeploy?path=/myapp"
命令行重启应用:
bash
curl -u tomcatscript:Script@123 "http://192.168.1.100:8080/manager/text/reload?path=/myapp"
六、Tomcat 日志管理(运维排障 “眼睛”,必须会看)
日志是排查问题的唯一依据,Tomcat 的日志都在目录下,重点掌握 “日志类型 + 查看方法 + 日志切割”。
logs
6.1 日志类型详解(6 种核心日志,知道各自作用)
| 日志文件名 | 日志类型 | 核心作用 | 运维常用场景 |
|---|---|---|---|
| catalina.out | 核心日志 | 记录 Tomcat 启动 / 停止过程、JVM 错误、应用的 System.out/err 输出(比如 Java 代码的) |
排查 Tomcat 启动失败、JVM 崩溃、应用控制台输出 |
| localhost.log | 主机日志 | 记录localhost主机的请求处理日志(比如应用初始化错误、Servlet 加载错误) | 排查应用部署失败、初始化报错 |
| localhost_access_log.*.txt | 访问日志 | 记录所有 HTTP 请求(包括请求 IP、时间、URL、状态码、响应大小、浏览器信息) | 分析访问量、排查异常请求(比如 404/500)、定位恶意 IP |
| manager.log | 管理后台日志 | 记录 Manager App 的操作日志(比如部署 / 卸载应用、重启应用) | 排查管理后台操作失败 |
| host-manager.log | 主机管理日志 | 记录 Host Manager 的操作日志(比如新增 / 修改虚拟主机) | 排查虚拟主机配置错误 |
| catalina.2024-05-20.log | 按日期切割的核心日志 | 和 catalina.out 内容类似,但按日期切割(默认不开启,需配置日志切割) | 按日期查询历史日志 |
6.2 日志查看命令(Linux 运维必学,附示例)
6.2.1 实时查看日志(排查正在发生的问题)
用命令,实时刷新日志内容:
tail -f
bash
# 实时查看catalina.out(最常用,排查启动失败、应用报错)
tail -f /usr/local/tomcat8.5/logs/catalina.out
# 实时查看访问日志(看用户请求情况,比如有没有404)
tail -f /usr/local/tomcat8.5/logs/localhost_access_log.2024-05-20.txt
# 查看日志的同时,过滤关键字(比如过滤“ERROR”,只看错误信息)
tail -f /usr/local/tomcat8.5/logs/catalina.out | grep "ERROR"
# 过滤关键字并显示上下文(-A 5:显示匹配行后5行;-B 5:显示前5行;-C 5:显示前后5行)
tail -f /usr/local/tomcat8.5/logs/catalina.out | grep -A 5 -B 5 "NullPointerException"
6.2.2 查看历史日志(排查已发生的问题)
用、
cat、
more、
less命令:
grep
bash
# 查看整个catalina.out(日志不大时用)
cat /usr/local/tomcat8.5/logs/catalina.out
# 分页查看日志(日志大时用,按空格翻页,q退出)
less /usr/local/tomcat8.5/logs/catalina.out
# 搜索日志中的关键字(比如搜索“500”错误,看哪些请求报500)
grep "500" /usr/local/tomcat8.5/logs/localhost_access_log.2024-05-20.txt
# 按日期搜索日志(比如搜索5月20日14点到15点的日志)
grep "20/May/2024:14" /usr/local/tomcat8.5/logs/localhost_access_log.2024-05-20.txt
6.3 日志切割(生产环境必配!避免日志文件过大)
默认情况下,会一直变大(可能几个 G 甚至几十 G),导致查看慢、占满磁盘,必须配置 “日志切割”—— 按日期 / 大小切割日志,保留指定天数的日志。
catalina.out
6.3.1 用 Linux 的
logrotate工具切割(推荐,系统自带)
logrotate
是 Linux 系统自带的日志切割工具,配置简单,适合生产环境。步骤:
logrotate
创建 logrotate 配置文件():
/etc/logrotate.d/tomcat8.5
bash
vi /etc/logrotate.d/tomcat8.5
写入以下配置(注释讲清楚每个参数):
bash
# 要切割的日志文件路径(catalina.out和访问日志)
/usr/local/tomcat8.5/logs/catalina.out
/usr/local/tomcat8.5/logs/localhost_access_log*.txt
{
daily # 按天切割(可选:weekly按周,monthly按月)
rotate 7 # 保留7天的日志,超过7天自动删除
compress # 切割后的日志用gzip压缩(节省磁盘空间)
delaycompress # 延迟压缩(保留最新的1个切割文件不压缩,方便查看)
missingok # 日志文件不存在时,不报错
notifempty # 日志文件为空时,不切割
create 640 tomcat tomcat # 切割后创建新日志文件,权限640,所有者tomcat:tomcat
sharedscripts # 所有日志文件切割完成后,只执行一次postrotate脚本
postrotate # 切割后执行的脚本(这里是让Tomcat重新生成日志文件,避免日志写入旧文件)
if [ -f /usr/local/tomcat8.5/temp/shutdown.port ]; then
# 向Tomcat的关闭端口发送命令,触发日志重新打开(不用重启Tomcat)
echo "SHUTDOWN" | nc localhost $(cat /usr/local/tomcat8.5/temp/shutdown.port) > /dev/null 2>&1
fi
endscript
}
测试配置是否生效:
bash
# 执行logrotate,强制切割日志(-f:强制;-v:显示详细过程)
logrotate -f -v /etc/logrotate.d/tomcat8.5
查看切割结果:,会看到切割后的日志(比如
ls /usr/local/tomcat8.5/logs/)。
catalina.out.1.gz
6.3.2 用 Tomcat 自带的日志切割(可选,配置复杂)
Tomcat 的文件可配置日志切割,但不如 logrotate 灵活,适合不想用系统工具的场景,核心是配置
conf/logging.properties的
java.util.logging.FileHandler(日志文件名格式)和
pattern(保留数量):
count
properties
# 在logging.properties里添加以下配置
handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
# 配置按日期切割catalina.log(注意:catalina.out不受这个配置控制,仍需logrotate)
1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.pattern = catalina.%d{yyyy-MM-dd}.log # 按日期切割
1catalina.org.apache.juli.FileHandler.maxDays = 7 # 保留7天
1catalina.org.apache.juli.FileHandler.formatter = java.util.logging.SimpleFormatter
七、Tomcat 性能调优(生产环境必做,应对高并发)
普通配置的 Tomcat 只能支持几百并发,高并发场景(比如秒杀、活动)会卡顿甚至崩溃,需要从 “JVM 调优” 和 “Tomcat 自身调优” 两方面入手。
7.1 JVM 调优(核心!Tomcat 跑在 JVM 上,JVM 性能决定 Tomcat 上限)
JVM 调优主要是 “配置内存参数” 和 “选择垃圾回收器”,参数配置在 Tomcat 的文件里。
bin/catalina.sh
7.1.1 核心 JVM 参数(必配,附说明和示例)
打开,在文件开头(
bin/catalina.sh下面)添加
#!/bin/sh参数(JVM 启动参数):
JAVA_OPTS
bash
# JVM调优参数(根据服务器内存调整,以下是4核8G服务器的推荐配置)
JAVA_OPTS="-server # 启用服务器模式(比客户端模式性能好,必加)
-Xms4g # 初始堆内存(JVM启动时分配的内存,建议和-Xmx一致,避免频繁扩容)
-Xmx4g # 最大堆内存(JVM能使用的最大内存,建议设为服务器物理内存的50%-70%,8G内存设4G)
-XX:MetaspaceSize=256m # 元空间初始大小(JDK8+用Metaspace替代PermGen,存储类信息,避免内存溢出)
-XX:MaxMetaspaceSize=512m # 元空间最大大小(根据应用依赖的jar包多少调整,一般256m-1G)
-XX:+UseG1GC # 使用G1垃圾回收器(JDK8+推荐,低延迟、高吞吐量,适合高并发)
-XX:MaxGCPauseMillis=200 # G1GC的最大停顿时间(目标200毫秒,根据需求调整)
-XX:ParallelGCThreads=4 # 并行GC线程数(建议设为CPU核心数,4核设4)
-XX:ConcGCThreads=2 # 并发GC线程数(一般是ParallelGCThreads的1/2)
-XX:+HeapDumpOnOutOfMemoryError # JVM内存溢出时,自动生成堆转储文件(.hprof),用于排查内存泄漏
-XX:HeapDumpPath=/usr/local/tomcat8.5/logs/ # 堆转储文件保存路径
-XX:+PrintGCDetails # 打印GC详细日志
-XX:+PrintGCDateStamps # 打印GC发生的时间戳
-Xloggc:/usr/local/tomcat8.5/logs/gc.log # GC日志保存路径
-Dfile.encoding=UTF-8 # 解决文件编码问题(避免中文乱码)
-Duser.timezone=GMT+8" # 设置时区(避免时间显示错误)
7.1.2 参数调整原则(根据服务器配置灵活改)
服务器内存 16G:;服务器内存 2G(小内存):
-Xms8g -Xmx8g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g;避免把
-Xms1g -Xmx1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m设为物理内存的 100%(留一部分给 Linux 系统和其他进程)。
-Xmx
7.1.3 验证 JVM 参数是否生效
bash
# 1. 重启Tomcat
systemctl restart tomcat8.5
# 2. 查Tomcat进程ID(PID)
ps -ef | grep tomcat | grep -v grep # 输出类似“tomcat 1234 ...”,1234是PID
# 3. 查看JVM参数(用jinfo命令,JDK自带)
jinfo -flags 1234
# 4. 查看GC日志(确认GC日志是否生成)
ls /usr/local/tomcat8.5/logs/gc.log
7.2 Tomcat 自身调优(基于 server.xml,优化请求处理)
7.2.1 配置线程池(提高并发处理能力,避免线程频繁创建销毁)
默认情况下,每个 Connector 自己管理线程,配置全局线程池后,多个 Connector 可共用线程,提高资源利用率。在的
server.xml标签里添加
Service(线程池),并让 Connector 关联它:
Executor
xml
<Service name="Catalina">
<!-- 1. 配置全局线程池 -->
<Executor name="tomcatThreadPool" <!-- 线程池名字,供Connector引用 -->
namePrefix="catalina-exec-" <!-- 线程名前缀,方便查进程 -->
maxThreads="1000" <!-- 最大线程数(比单个Connector的maxThreads大,根据并发调整) -->
minSpareThreads="50" <!-- 最小空闲线程数(保持50个空闲线程,应对突发请求) -->
maxIdleTime="60000" <!-- 线程最大空闲时间(60秒,空闲超过60秒销毁,释放资源) -->
prestartminSpareThreads="true" <!-- 启动时就创建minSpareThreads个线程,避免首次请求耗时 -->
maxQueueSize="1000" /> <!-- 请求队列大小(线程满了后,请求排队,超过队列大小返回503) -->
<!-- 2. Connector关联线程池(指定executor="线程池名") -->
<Connector executor="tomcatThreadPool" <!-- 引用上面的线程池 -->
port="80"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="30000"
redirectPort="443"
URIEncoding="UTF-8"
enableLookups="false"
compression="on" />
</Service>
7.2.2 禁用不必要的组件(减少资源占用)
禁用 AJP 协议:如果不用 Apache 服务器配合 Tomcat,删掉里的 AJP Connector(
server.xml那个);关闭管理后台:生产环境不用 Manager App 和 Host Manager,删除
port="8009"下的
webapps和
manager目录(或改权限为不可访问);禁用 WebDAV:如果应用不用 WebDAV(文件上传协议),在
host-manager里注释掉 WebDAV 相关的
web.xml和
servlet(减少安全风险和资源占用)。
servlet-mapping
7.2.3 静态资源优化(让 Tomcat 处理静态资源更快)
Tomcat 处理静态资源(HTML、CSS、JS、图片)的性能不如 Nginx,但可通过配置优化:
xml
<!-- 在Context里配置静态资源缓存 -->
<Context docBase="/data/apps/myapp" reloadable="false">
<!-- 配置静态资源缓存:对/css、/js、/images目录的文件,缓存30天 -->
<Resources cachingAllowed="true" cacheMaxSize="102400"> <!-- 缓存最大100MB -->
<PreResources base="/data/apps/myapp/static"
webAppMount="/static"
cachingAllowed="true"
cacheMaxSize="51200" /> <!-- 单独配置/static目录的缓存 -->
</Resources>
<!-- 配置Expires头:告诉浏览器缓存静态资源30天 -->
<Valve className="org.apache.catalina.valves.ExpiresFilter"
expiresDefault="access plus 30 days" <!-- 默认缓存30天 -->
expiresByType text/css="access plus 30 days"
expiresByType application/javascript="access plus 30 days"
expiresByType image/jpeg="access plus 30 days"
expiresByType image/png="access plus 30 days" />
</Context>
八、Tomcat 安全加固(生产环境必做,避免被入侵)
运维不仅要让 Tomcat 跑起来,还要保证它安全,重点从 “权限控制”“配置安全”“HTTPS”“漏洞修复” 四方面入手。
8.1 最小权限原则(从根源降低风险)
运行用户:坚决不用 root 跑 Tomcat,用专门的用户(前面安装时已配置);目录权限:
tomcat
目录:设为只读(
webapps),避免应用被篡改;
chmod 755 /usr/local/tomcat8.5/webapps/目录:设为只读(
conf),只有
chmod 750 /usr/local/tomcat8.5/conf/用户能读,其他用户不能访问;
tomcat目录:设为
logs用户独有(
tomcat),避免日志泄露敏感信息; 禁用不必要的用户:删除 Linux 系统里不用的用户(比如
chmod 700 /usr/local/tomcat8.5/logs/、
ftp),避免被利用。
games
8.2 配置安全(避免配置漏洞)
8.2.1 禁用目录浏览(防止目录结构泄露)
默认情况下,如果应用目录下没有欢迎页,Tomcat 会显示目录列表(泄露文件结构),需禁用:
全局禁用:在里找到
conf/web.xml标签下的
<servlet> servlet,添加
default:
listings="false"
xml
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value> <!-- 禁用目录浏览,必加! -->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
单个应用禁用:在应用的里添加同样的配置(优先级高于全局)。
WEB-INF/web.xml
8.2.2 限制管理后台访问(仅允许指定 IP)
前面配置管理后台时已讲过,通过的
context.xml限制 IP,生产环境建议只允许公司内网 IP 访问,比如:
RemoteAddrValve
xml
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="192.168.1.*|10.0.0.*" /> <!-- 只允许192.168.1.xxx和10.0.0.xxx访问 -->
8.2.3 隐藏 Tomcat 版本信息(避免被针对性攻击)
默认情况下,Tomcat 会在 HTTP 响应头里暴露版本(比如),黑客可根据版本找漏洞,需隐藏:
Server: Apache-Coyote/1.1
下载包(和 Tomcat 版本一致),用压缩工具打开;进入
tomcat-coyote.jar目录,找到
org/apache/coyote/http11文件;用反编译工具(比如 JD-GUI)打开
Http11NioProtocol.class,修改
Http11NioProtocol.class变量的值(比如把
serverInfo改成
Apache-Coyote/1.1);替换原
MyServer/1.0里的
tomcat-coyote.jar文件;重启 Tomcat,用
Http11NioProtocol.class查看响应头,
curl -I http://服务器IP字段已改为自定义值。
Server
8.3 配置 HTTPS(加密传输,避免数据泄露)
现在所有网站都要求 HTTPS(浏览器会提示 “不安全”),Tomcat 配置 HTTPS 步骤:
8.3.1 生成 SSL 证书(两种方式:自签证书 / CA 证书)
自签证书(测试环境用,浏览器会提示不安全):用 JDK 自带的命令生成:
keytool
bash
# 生成自签证书(-keystore:证书保存路径;-alias:证书别名;-keyalg:加密算法;-validity:有效期天数)
keytool -genkey -v -keystore /usr/local/tomcat8.5/conf/ssl/tomcat_ssl.jks -alias tomcat_ssl -keyalg RSA -validity 3650
# 按提示输入信息(密码:比如TomcatSSL@123;名字与姓氏:输入服务器域名,比如www.xxx.com;其他信息随便填)
CA 证书(生产环境用,浏览器信任,需从阿里云 / 腾讯云购买,比如 Let's Encrypt 免费证书):购买后下载证书文件(一般是或
xxx.pfx格式),上传到
xxx.jks目录。
/usr/local/tomcat8.5/conf/ssl/
8.3.2 在 server.xml 里配置 HTTPS Connector
xml
<!-- HTTPS Connector(port="443"是HTTPS默认端口,浏览器可省略) -->
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="1000" minSpareThreads="50"
connectionTimeout="30000"
URIEncoding="UTF-8"
enableLookups="false"
SSLEnabled="true" <!-- 开启SSL -->
scheme="https" <!-- 协议 scheme 为 https -->
secure="true" <!-- 标记为安全连接 -->
clientAuth="false" <!-- 是否要求客户端提供证书(false:不要求,一般用这个) -->
sslProtocol="TLS" <!-- SSL协议(TLS是主流,避免用SSLv3) -->
keystoreFile="/usr/local/tomcat8.5/conf/ssl/tomcat_ssl.jks" <!-- 证书路径 -->
keystorePass="TomcatSSL@123" <!-- 证书密码(生成时设置的) -->
keystoreType="JKS" <!-- 证书类型(JKS是Java默认类型,PFX证书填PKCS12) -->
ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" /> <!-- 启用安全的加密套件,避免弱加密 -->
8.3.3 强制 HTTP 跳转 HTTPS(让所有 HTTP 请求自动跳 HTTPS)
两种方式,选一种即可:
用 Tomcat 的配置(在
SecurityConstraint末尾添加):
conf/web.xml
xml
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern> <!-- 所有路径都强制HTTPS -->
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee> <!-- 强制加密传输 -->
</user-data-constraint>
</security-constraint>
用 Nginx 反向代理(推荐,性能更好,后续 “Tomcat 与 Nginx 配合” 会讲)。
8.4 漏洞修复(定期更新,避免已知漏洞)
定期更新 Tomcat 版本:关注 Tomcat 官网的安全公告(Tomcat Security),有漏洞时及时升级到修复版本(比如之前的 Ghostcat 漏洞,影响 Tomcat 6/7/8/9,需升级到指定版本);扫描漏洞:用工具(比如 Nessus、OpenVAS)定期扫描 Tomcat,发现漏洞及时修复;禁用危险功能:比如禁用、
PUT等 HTTP 方法(在
DELETE里配置
web.xml),避免被利用上传恶意文件。
HttpMethodConstraint
九、Tomcat 问题排查(运维核心技能,附常见问题)
遇到问题不要慌,按 “看日志→查配置→验环境” 的流程排查,90% 的问题都能解决。
9.1 常见问题及排查步骤(附示例)
9.1.1 问题 1:Tomcat 启动失败,执行
systemctl status tomcat8.5显示 “failed”
systemctl status tomcat8.5
排查步骤:
看核心日志(catalina.out,最直接):
bash
tail -n 100 /usr/local/tomcat8.5/logs/catalina.out # 看最后100行日志
常见错误及解决:
错误 1:(端口被占用)日志里有 “8080” 或 “8005” 端口被占用的提示,解决:
Address already in use
bash
# 查占用端口的进程(比如8080端口)
ss -tulpn | grep 8080 # 输出类似“LISTEN 0 100 :::8080 :::* users:(("java",pid=5678,fd=123))”
# 杀死占用进程(pid=5678)
kill -9 5678
# 重启Tomcat
systemctl restart tomcat8.5
错误 2:(JDK 环境变量没配置)解决:重新配置 JDK 环境变量(参考 “二、2.2”),执行
JAVA_HOME is not set and could not be found生效,再重启 Tomcat;错误 3:
source /etc/profile(权限不足)日志里有 “无法访问 conf/server.xml” 或 “无法执行 bin/startup.sh”,解决:
Permission denied
bash
# 改Tomcat目录所有权为tomcat用户
chown -R tomcat:tomcat /usr/local/tomcat8.5/
# 改bin目录脚本执行权限
chmod +x /usr/local/tomcat8.5/bin/*.sh
9.1.2 问题 2:应用部署后访问报 “404 Not Found”
排查步骤:
确认应用是否部署成功:
看目录(或
webapps目录)是否有应用的解压目录(比如
appBase);看 Manager App 后台的 “Applications” 列表,是否有
myapp应用(状态是 “running”); 确认访问路径是否正确:
/myapp
访问路径格式:,比如应用上下文是
http://服务器IP:端口/应用上下文路径,则路径是
/myapp;如果应用的上下文路径是
http://192.168.1.100:8080/myapp(根路径),则访问
/(需配置 Context 的
http://服务器IP:端口); 看localhost.log 日志:
path=""
bash
grep "myapp" /usr/local/tomcat8.5/logs/localhost.log # 看应用部署是否有错误
常见错误:(应用初始化失败),需看应用自身的日志(比如
Context initialization failed)。
myapp/WEB-INF/logs/
9.1.3 问题 3:应用访问报 “500 Internal Server Error”
排查步骤:
看应用日志(最关键,500 一般是应用代码报错):
应用日志通常在目录下,查看错误信息(比如
myapp/WEB-INF/logs/、
NullPointerException); 看 catalina.out 日志(查看 Java 异常堆栈):
SQLSyntaxErrorException
bash
grep -A 20 -B 5 "ERROR" /usr/local/tomcat8.5/logs/catalina.out # 看错误上下文
常见错误及解决:
错误 1:(空指针异常):通知开发修复代码;错误 2:
NullPointerException(数据库 SQL 错误):检查数据库连接配置(应用的
SQLSyntaxErrorException或
db.properties)、SQL 语句是否正确;错误 3:
application.yml(类找不到):应用依赖的 jar 包缺失,让开发补全依赖。
ClassNotFoundException
9.1.4 问题 4:Tomcat 运行缓慢,请求响应时间长
排查步骤:
查服务器资源(CPU、内存、磁盘 I/O):
bash
top # 看CPU和内存使用率(%Cpu(s)超过90%、%Mem超过90%说明资源不足)
free -h # 看内存使用(available不足说明内存不够)
iostat -x 1 # 看磁盘I/O(%util超过90%说明磁盘忙)
资源不足解决:升级服务器配置,或关闭其他占用资源的进程;
排查步骤:
查 JVM 状态(是否有内存泄漏、GC 频繁):
bash
# 用jstat查看GC情况(PID是Tomcat进程ID,每2秒输出一次,共输出10次)
jstat -gcutil 1234 2000 10
# 输出解读:S0(Survivor0区使用率)、S1(Survivor1区使用率)、E(Eden区使用率)、O(老年代使用率)、M(元空间使用率)、CCS(压缩类空间使用率)、YGC(Young GC次数)、YGCT(Young GC耗时)、FGC(Full GC次数)、FGCT(Full GC耗时)、GCT(总GC耗时)
# 异常情况:FGC频繁(比如每分钟几次)、FGCT累计时间长(比如超过10秒)→ 可能内存泄漏或JVM参数不合理
解决:如果老年代(O)使用率持续接近 100%,可能是内存泄漏,用导出堆内存分析:
jmap
bash
# 导出堆转储文件(需JVM参数配置-XX:+HeapDumpOnOutOfMemoryError,或手动导出)
jmap -dump:format=b,file=/tmp/tomcat_heap.hprof 1234
# 用MAT(Memory Analyzer Tool)工具分析hprof文件,定位内存泄漏的对象(比如未释放的数据库连接、大集合)
若 GC 正常但响应慢,查线程状态:
bash
# 用jstack导出线程栈(查看是否有线程阻塞、死锁)
jstack 1234 > /tmp/tomcat_threads.txt
# 分析线程栈:搜索“BLOCKED”(阻塞)、“DEADLOCK”(死锁),比如数据库连接池满导致线程等待
查 Tomcat 线程和连接:
线程池是否满了:查看中
server.xml配置,对比当前活跃线程数(可通过 Manager App 的 “Server Status” 查看,或用
maxThreads看总线程数);连接数是否超限:用
ps -T -p 1234 | wc -l看当前连接数,若接近
ss -tulpn | grep java | wc -l配置,需调大该参数;慢请求排查:在访问日志(
maxConnections)中找响应时间长的请求(日志格式需配置
localhost_access_log参数,记录响应时间毫秒数),比如:
%D
bash
# 访问日志配置(在server.xml的Connector中添加):
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %D" />
# %D:响应时间(毫秒),筛选响应时间超过5000ms的请求
grep -E '" [0-9]{4,} "' localhost_access_log.2024-05-20.txt | awk '{if($10>5000) print $0}'
找到慢请求后,通知开发优化对应的接口代码。
9.1.5 问题 5:HTTPS 配置后无法访问(浏览器提示 “无法连接” 或 “证书错误”)
排查步骤:
确认 HTTPS 端口是否启动:
bash
ss -tulpn | grep 443 # 若没有LISTEN,说明HTTPS Connector配置错误
常见错误:证书路径错误(填错)、证书密码错误(
keystoreFile与生成时不一致),查看
keystorePass日志,会有 “Invalid keystore password” 等提示,修正配置后重启 Tomcat。
catalina.out
浏览器证书错误处理:
自签证书:浏览器会提示 “不安全”,点击 “高级”→“继续访问”(仅测试环境用);CA 证书:若提示 “证书无效”,检查证书是否过期、域名是否与证书绑定的域名一致(比如证书绑定,访问
www.xxx.com会报错),重新申请正确的证书。
xxx.com
防火墙是否开放 443 端口:
bash
# CentOS查看防火墙规则
firewall-cmd --list-ports | grep 443
# 若未开放,添加规则并重启防火墙
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
9.1.6 问题 6:日志文件过大导致磁盘满(
df -h显示磁盘使用率 100%)
df -h
排查步骤:
确认大文件位置:
bash
# 查找logs目录下大于1G的文件
find /usr/local/tomcat8.5/logs/ -type f -size +1G
# 通常是未切割的catalina.out或访问日志
临时清理(避免服务中断):
不要直接日志文件(删除后 Tomcat 仍会向已删除的文件句柄写入,磁盘空间不释放),正确做法:
rm
bash
# 清空文件内容(保留文件句柄)
> /usr/local/tomcat8.5/logs/catalina.out
# 或用logrotate强制切割(之前配置过的话)
logrotate -f /etc/logrotate.d/tomcat8.5
彻底解决:
检查日志切割配置是否生效(参考 “六、6.3”),确保能按计划切割并删除旧日志;若应用日志输出过多(比如频繁打印
logrotate),通知开发优化日志级别(只打必要的 INFO/ERROR,减少 DEBUG 日志)。
System.out
十、Tomcat 与其他工具配合(生产环境常用架构)
实际工作中,Tomcat 很少单独使用,通常会和 “反向代理(Nginx)”“负载均衡”“监控工具” 配合,形成完整的 Web 服务架构。
10.1 Tomcat + Nginx(必学!生产环境标配)
Nginx 作为反向代理服务器,放在 Tomcat 前面,负责 “接收用户请求→转发给 Tomcat→返回结果给用户”,优势:
处理静态资源更快(HTML/CSS/JS/ 图片),减轻 Tomcat 压力;实现负载均衡(多 Tomcat 实例分摊请求);提供 HTTPS 支持(比 Tomcat 配置更简单,性能更好)。
10.1.1 基础反向代理配置(Nginx 转发请求给单个 Tomcat)
安装 Nginx(以 CentOS 为例):
bash
yum install -y nginx
systemctl start nginx
systemctl enable nginx
配置 Nginx():
/etc/nginx/conf.d/tomcat_proxy.conf
nginx
server {
listen 80;
server_name www.xxx.com; # 你的域名
# 静态资源直接由Nginx处理(路径根据实际情况改)
location /static/ {
root /data/apps/myapp/; # 静态资源目录(比如/myapp/static/下的文件)
expires 30d; # 缓存30天
}
# 其他请求转发给Tomcat
location / {
proxy_pass http://127.0.0.1:8080; # Tomcat的地址和端口
proxy_set_header Host $host; # 传递主机名给Tomcat
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP给Tomcat
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(http/https)
}
}
重启 Nginx 生效:
bash
nginx -t # 检查配置是否有误
systemctl restart nginx
访问,Nginx 会自动转发请求到 Tomcat 的 8080 端口。
http://www.xxx.com
10.1.2 负载均衡配置(多 Tomcat 实例分摊压力)
当单个 Tomcat 扛不住并发时,可部署多个 Tomcat 实例(同一服务器或不同服务器),用 Nginx 做负载均衡。步骤:
部署多个 Tomcat(比如 2 个,端口分别为 8080 和 8081,注意的端口不能冲突);Nginx 配置负载均衡(
server.xml):
/etc/nginx/conf.d/tomcat_loadbalance.conf
nginx
# 定义负载均衡集群(my_tomcat_cluster)
upstream my_tomcat_cluster {
server 127.0.0.1:8080 weight=1; # 第一个Tomcat,权重1(权重越高,分配的请求越多)
server 127.0.0.1:8081 weight=1; # 第二个Tomcat,权重1
# 可选配置:
# ip_hash; # 按客户端IP分配请求(解决会话共享问题,同一IP始终访问同一Tomcat)
# max_fails=2 fail_timeout=30s; # 连续2次请求失败,30秒内不再分配到该Tomcat
}
server {
listen 80;
server_name www.xxx.com;
location / {
proxy_pass http://my_tomcat_cluster; # 转发到集群
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
重启 Nginx,此时请求会自动分配到 8080 和 8081 的 Tomcat 实例。
10.2 Tomcat 监控(运维必备,及时发现问题)
生产环境需实时监控 Tomcat 的状态(线程数、内存使用、请求量),常用工具:
10.2.1 JConsole(JDK 自带,简单直观)
JConsole 是 JDK 自带的图形化监控工具,可监控 JVM 内存、线程、类加载、VM 摘要等。使用步骤:
在 Tomcat 的中添加 JMX 监控参数(允许远程连接):
catalina.sh
bash
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=1099 # JMX端口
-Dcom.sun.management.jmxremote.authenticate=false # 关闭认证(测试环境用)
-Dcom.sun.management.jmxremote.ssl=false # 关闭SSL
-Djava.rmi.server.hostname=192.168.1.100" # 服务器IP
重启 Tomcat,开放 1099 端口防火墙;本地电脑打开 JConsole(Windows:;Linux:
JDK安装目录/bin/jconsole.exe命令),连接
jconsole,即可查看监控数据。
192.168.1.100:1099
10.2.2 Prometheus + Grafana(企业级监控,可视化强)
适合大规模集群监控,Prometheus 采集数据,Grafana 展示图表。核心步骤:
部署 Prometheus 和 Grafana(参考官方文档);给 Tomcat 安装插件(将 JMX 数据转换为 Prometheus 格式);配置 Prometheus 抓取 Tomcat 的监控数据,Grafana 导入 Tomcat 监控模板(比如 ID 为 8563 的模板),即可看到线程数、GC 次数、响应时间等可视化图表。
prometheus-jmx-exporter
11避坑总结(工作中少走弯路)
版本匹配:JDK 和 Tomcat 版本必须对应(比如 Tomcat 8.5 配 JDK 1.8),否则启动报错;权限第一:永远不用 root 运行 Tomcat,目录权限严格控制(读 / 写 / 执行分离);日志优先:任何问题先看日志(catalina.out、访问日志),90% 的答案在日志里;备份配置:修改等核心配置前,先备份(
server.xml),出错可快速恢复;定期更新:关注 Tomcat 安全漏洞,及时升级到稳定版本,避免用太老的版本(比如 Tomcat 6 已停止维护)。
cp server.xml server.xml.bak
















暂无评论内容