Linux运维工程师Tomcat系统学习体系

一、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
(改文件权限)、
chown
(改文件所有者)(后续 Tomcat 不能用 root 跑,必须改权限)。

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/

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

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 目录结构详解(运维必须记熟!)

解压后的
tomcat8.5
目录里有 7 个核心子目录,每个目录的作用直接关联后续配置 / 排查,用表格讲清楚:

目录名 核心作用 运维常用操作举例
bin 存放 Tomcat 启停脚本(
startup.sh
启动、
shutdown.sh
停止)、环境配置脚本
执行
./startup.sh
启动 Tomcat
conf 存放 Tomcat 所有配置文件(核心!比如
server.xml

web.xml

server.xml
调整端口、改
web.xml
设欢迎页
webapps 存放 Web 应用的目录(部署的 war 包 / 解压后的应用都放这)
xxx.war
包丢这里,Tomcat 会自动解压
logs 存放 Tomcat 所有日志(排查问题全靠它!)
catalina.out
查启动失败原因
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
管理,运维推荐)

手动执行脚本麻烦,生产环境一般把 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
(比如
http://192.168.1.100:8080
),出现 Tomcat 默认页面(有 “Apache Tomcat” 字样)说明成功;命令行访问(服务器没图形界面时用):

bash



# 用curl命令访问,出现HTML内容说明成功
curl http://localhost:8080

访问失败排查:先查防火墙(CentOS 关闭防火墙:
systemctl stop firewalld
;Ubuntu:
ufw disable
),再查 Tomcat 状态(
systemctl status tomcat8.5
),最后看日志(
cat /usr/local/tomcat8.5/logs/catalina.out
)。

四、Tomcat 核心配置(运维进阶核心,工作中 80% 场景用这个)

这部分是 “重头戏”,掌握后能应对 90% 的日常运维需求(比如改端口、部署应用、设密码)。核心配置文件都在
conf
目录下,重点讲 3 个文件:
server.xml
(主配置)、
web.xml
(应用全局配置)、
tomcat-users.xml
(用户权限)。

4.1 主配置文件:
server.xml
(Tomcat 的 “大脑”)


server.xml
定义了 Tomcat 的核心组件(比如端口、请求处理引擎、应用主机),所有 “全局级” 配置都改这里。用 “组件拆解” 的方式讲,更易懂:

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>


port="8005"
:Tomcat 的 “关闭端口”(仅本地能用,发送 “SHUTDOWN” 命令就停止 Tomcat),一般不用改;
shutdown="SHUTDOWN"
:关闭命令的关键字,改不改都行,安全起见可改个复杂的(比如
shutdown="MyTomcatShutdown123"
)。

② Service 组件(关联 “连接器” 和 “引擎”,相当于 “桥梁”)

xml



<Service name="Catalina">
  <!-- 里面是Connector(连接器)和Engine(引擎) -->
</Service>


name="Catalina"
:Service 的名字,默认即可,多个 Service 可改不同名(很少用)。

③ 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" />

运维常用配置项(改这些就够了)

配置项 作用说明 示例(优化后)

port
HTTP 端口(默认 8080,生产环境一般改 80(HTTP 默认端口,浏览器可省略端口))
port="80"

protocol
协议类型(
HTTP/1.1
即可,高版本可改
org.apache.coyote.http11.Http11NioProtocol
(NIO 模式,性能更好))

protocol="org.apache.coyote.http11.Http11NioProtocol"

connectionTimeout
连接超时时间(毫秒,默认 20000=20 秒,超时断开连接,避免资源占用)
connectionTimeout="30000"

redirectPort
HTTPS 重定向端口(当请求需要 HTTPS 时,自动跳这个端口,后续配 HTTPS 会用到)
redirectPort="443"
(HTTPS 默认端口)

maxThreads
最大线程数(处理请求的线程上限,默认 200,高并发场景可改 500-1000)
maxThreads="500"

minSpareThreads
最小空闲线程数(默认 10,保持一定空闲线程,避免请求来时创建线程耗时)
minSpareThreads="20"

maxConnections
最大连接数(同时处理的请求数,默认 10000,根据服务器内存调整)
maxConnections="20000"

示例:优化后的 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>


name="Catalina"
:和 Service 名字对应,默认即可;
defaultHost="localhost"
:默认主机名(当请求没有指定主机时,用这个),一般改服务器的域名(比如
defaultHost="www.xxx.com"
)。

⑤ Host 组件(虚拟主机,一个 Host 对应一个域名 / 应用)

xml



<Host name="localhost"  appBase="webapps"
      unpackWARs="true" autoDeploy="true">
  <!-- 里面是Context(应用上下文)组件 -->
</Host>

运维常用配置项

配置项 作用说明 示例

name
主机名(域名),比如
name="www.xxx.com"
,访问这个域名就对应此 Host

name="www.xxx.com"

appBase
应用基础目录(默认
webapps
,即
webapps
目录下的应用归这个 Host 管理)

appBase="webapps"

unpackWARs
是否自动解压 war 包(
true
:丢 war 包到
appBase
,自动解压;
false
:不解压,直接运行 war 包)

unpackWARs="true"

autoDeploy
是否自动部署(
true
:新增 / 修改应用时,Tomcat 自动加载,不用重启;
false
:需手动重启)

autoDeploy="true"

xmlBase
应用 XML 配置目录(可选,默认
conf/Catalina/[Host名]
,比如
conf/Catalina/www.xxx.com
,在这里放应用配置文件,比直接改 server.xml 灵活)

xmlBase="conf/Catalina/www.xxx.com"

示例:配置多虚拟主机(比如一个服务器跑两个应用:
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

blog
目录,分别放对应应用的 war 包。

⑥ 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:在
xmlBase
目录下建 XML 文件(推荐,不用重启 Tomcat)
比如 Host 的
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
(所有应用共用的配置)


conf/web.xml
是 Tomcat 的全局 Web 应用配置文件,所有部署在 Tomcat 里的应用都会继承这里的配置,常用配置:

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 类型是 “文件类型与浏览器处理方式的映射”,比如
text/html
对应 HTML 页面,
image/jpeg
对应 JPG 图片。如果浏览器访问
xxx.pdf
时直接下载而非预览,可能是 MIME 类型没配置:

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 有两个管理后台(
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 服务器本地访问管理后台(
http://localhost:8080/manager/html
),远程浏览器访问会报 403,需要改 IP 限制:

改 Manager App 的 IP 限制:
vi /usr/local/tomcat8.5/webapps/manager/META-INF/context.xml
找到
<Valve>
标签,把
allow
改成你的 IP(比如
192.168.1.*
允许内网访问,
0.0.0.0/0
允许所有 IP,生产环境不推荐
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
同上,修改
allow
的值。重启 Tomcat:
systemctl restart tomcat8.5
,之后远程浏览器访问
http://服务器IP:8080/manager/html
,输入用户名
tomcatadmin
和密码
Tomcat@123456
即可登录。

五、Web 应用部署(运维核心工作:把代码跑起来)

部署应用是运维的日常工作,Tomcat 支持 4 种部署方式,从简单到复杂都要会。

5.1 方式 1:webapps 目录自动部署(最简单,适合新手 / 测试环境)

原理:Tomcat 的
appBase
目录(默认
webapps
)会自动监控文件变化,把 war 包丢进去就自动部署。步骤:

把开发给的
xxx.war
包(比如
myapp.war
)上传到
webapps
目录(或 Host 对应的
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
里的
myapp.war
包,Tomcat 会自动重新解压(
autoDeploy="true"
时);删除应用:删除
webapps
里的
myapp.war

myapp
目录,Tomcat 会自动卸载。

5.2 方式 2:Manager App 后台部署(图形化,适合临时部署 / 非 root 用户)

原理:通过 Tomcat 的管理后台(
/manager/html
)上传 war 包,不用操作命令行,适合运维没服务器 root 权限的场景。步骤:

浏览器访问
http://服务器IP:8080/manager/html
,登录(之前配置的
tomcatadmin
用户);找到 “Deploy” 模块,选择 “WAR file to deploy”;点击 “Browse” 选择本地的
myapp.war
包,点击 “Deploy”;部署成功后,在 “Applications” 列表里会看到
/myapp
,点击路径即可访问;更新 / 删除应用:在 “Applications” 列表里,点击
/myapp
对应的 “Reload”(更新)或 “Undeploy”(删除)。

5.3 方式 3:Context XML 配置部署(灵活,适合生产环境)

原理:在
xmlBase
目录(比如
conf/Catalina/www.xxx.com
)下建 XML 文件,指定应用的实际路径,优点是 “应用目录可放任意位置,不用丢 webapps”,且改配置不用重启 Tomcat(
autoDeploy="true"
时)。步骤:


myapp
解压后的目录(不是 war 包)放到自定义路径,比如
/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
;更新应用:直接替换
/data/apps/myapp
目录下的文件,然后在 Manager 后台点击 “Reload”(或删除
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:
systemctl restart tomcat8.5
;命令行部署 war 包(本地或服务器上执行):

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 代码的
System.out.println
排查 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 日志切割(生产环境必配!避免日志文件过大)

默认情况下,
catalina.out
会一直变大(可能几个 G 甚至几十 G),导致查看慢、占满磁盘,必须配置 “日志切割”—— 按日期 / 大小切割日志,保留指定天数的日志。

6.3.1 用 Linux 的
logrotate
工具切割(推荐,系统自带)


logrotate
是 Linux 系统自带的日志切割工具,配置简单,适合生产环境。步骤:

创建 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 的
conf/logging.properties
文件可配置日志切割,但不如 logrotate 灵活,适合不想用系统工具的场景,核心是配置
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
下面)添加
JAVA_OPTS
参数(JVM 启动参数):

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:
-Xms8g -Xmx8g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g
;服务器内存 2G(小内存):
-Xms1g -Xmx1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
;避免把
-Xmx
设为物理内存的 100%(留一部分给 Linux 系统和其他进程)。

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
标签里添加
Executor
(线程池),并让 Connector 关联它:

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,删掉
server.xml
里的 AJP Connector(
port="8009"
那个);关闭管理后台:生产环境不用 Manager App 和 Host Manager,删除
webapps
下的
manager

host-manager
目录(或改权限为不可访问);禁用 WebDAV:如果应用不用 WebDAV(文件上传协议),在
web.xml
里注释掉 WebDAV 相关的
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
用户独有(
chmod 700 /usr/local/tomcat8.5/logs/
),避免日志泄露敏感信息; 禁用不必要的用户:删除 Linux 系统里不用的用户(比如
ftp

games
),避免被利用。

8.2 配置安全(避免配置漏洞)

8.2.1 禁用目录浏览(防止目录结构泄露)

默认情况下,如果应用目录下没有欢迎页,Tomcat 会显示目录列表(泄露文件结构),需禁用:

全局禁用:在
conf/web.xml
里找到
<servlet>
标签下的
default
 servlet,添加
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

RemoteAddrValve
限制 IP,生产环境建议只允许公司内网 IP 访问,比如:

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-coyote.jar
包(和 Tomcat 版本一致),用压缩工具打开;进入
org/apache/coyote/http11
目录,找到
Http11NioProtocol.class
文件;用反编译工具(比如 JD-GUI)打开
Http11NioProtocol.class
,修改
serverInfo
变量的值(比如把
Apache-Coyote/1.1
改成
MyServer/1.0
);替换原
tomcat-coyote.jar
里的
Http11NioProtocol.class
文件;重启 Tomcat,用
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

DELETE
等 HTTP 方法(在
web.xml
里配置
HttpMethodConstraint
),避免被利用上传恶意文件。

九、Tomcat 问题排查(运维核心技能,附常见问题)

遇到问题不要慌,按 “看日志→查配置→验环境” 的流程排查,90% 的问题都能解决。

9.1 常见问题及排查步骤(附示例)

9.1.1 问题 1:Tomcat 启动失败,执行
systemctl status tomcat8.5
显示 “failed”

排查步骤:

看核心日志(catalina.out,最直接):

bash


tail -n 100 /usr/local/tomcat8.5/logs/catalina.out  # 看最后100行日志

常见错误及解决
错误 1:
Address already in use
(端口被占用)日志里有 “8080” 或 “8005” 端口被占用的提示,解决:

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:
JAVA_HOME is not set and could not be found
(JDK 环境变量没配置)解决:重新配置 JDK 环境变量(参考 “二、2.2”),执行
source /etc/profile
生效,再重启 Tomcat;错误 3:
Permission denied
(权限不足)日志里有 “无法访问 conf/server.xml” 或 “无法执行 bin/startup.sh”,解决:

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
目录)是否有应用的解压目录(比如
myapp
);看 Manager App 后台的 “Applications” 列表,是否有
/myapp
应用(状态是 “running”); 确认访问路径是否正确
访问路径格式:
http://服务器IP:端口/应用上下文路径
,比如应用上下文是
/myapp
,则路径是
http://192.168.1.100:8080/myapp
;如果应用的上下文路径是
/
(根路径),则访问
http://服务器IP:端口
(需配置 Context 的
path=""
); 看localhost.log 日志

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

SQLSyntaxErrorException
); 看 catalina.out 日志(查看 Java 异常堆栈):

bash


grep -A 20 -B 5 "ERROR" /usr/local/tomcat8.5/logs/catalina.out  # 看错误上下文

常见错误及解决
错误 1:
NullPointerException
(空指针异常):通知开发修复代码;错误 2:
SQLSyntaxErrorException
(数据库 SQL 错误):检查数据库连接配置(应用的
db.properties

application.yml
)、SQL 语句是否正确;错误 3:
ClassNotFoundException
(类找不到):应用依赖的 jar 包缺失,让开发补全依赖。

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

maxThreads
配置,对比当前活跃线程数(可通过 Manager App 的 “Server Status” 查看,或用
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 &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; %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
与生成时不一致),查看
catalina.out
日志,会有 “Invalid keystore password” 等提示,修正配置后重启 Tomcat。

浏览器证书错误处理

自签证书:浏览器会提示 “不安全”,点击 “高级”→“继续访问”(仅测试环境用);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%)

排查步骤:

确认大文件位置

bash



# 查找logs目录下大于1G的文件
find /usr/local/tomcat8.5/logs/ -type f -size +1G
# 通常是未切割的catalina.out或访问日志

临时清理(避免服务中断)

不要直接
rm
日志文件(删除后 Tomcat 仍会向已删除的文件句柄写入,磁盘空间不释放),正确做法:

bash



# 清空文件内容(保留文件句柄)
> /usr/local/tomcat8.5/logs/catalina.out
# 或用logrotate强制切割(之前配置过的话)
logrotate -f /etc/logrotate.d/tomcat8.5

彻底解决

检查日志切割配置是否生效(参考 “六、6.3”),确保
logrotate
能按计划切割并删除旧日志;若应用日志输出过多(比如频繁打印
System.out
),通知开发优化日志级别(只打必要的 INFO/ERROR,减少 DEBUG 日志)。

十、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

访问
http://www.xxx.com
,Nginx 会自动转发请求到 Tomcat 的 8080 端口。

10.1.2 负载均衡配置(多 Tomcat 实例分摊压力)

当单个 Tomcat 扛不住并发时,可部署多个 Tomcat 实例(同一服务器或不同服务器),用 Nginx 做负载均衡。步骤:

部署多个 Tomcat(比如 2 个,端口分别为 8080 和 8081,注意
server.xml
的端口不能冲突);Nginx 配置负载均衡(
/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 的
catalina.sh
中添加 JMX 监控参数(允许远程连接):

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:
JDK安装目录/bin/jconsole.exe
;Linux:
jconsole
命令),连接
192.168.1.100:1099
,即可查看监控数据。

10.2.2 Prometheus + Grafana(企业级监控,可视化强)

适合大规模集群监控,Prometheus 采集数据,Grafana 展示图表。核心步骤:

部署 Prometheus 和 Grafana(参考官方文档);给 Tomcat 安装
prometheus-jmx-exporter
插件(将 JMX 数据转换为 Prometheus 格式);配置 Prometheus 抓取 Tomcat 的监控数据,Grafana 导入 Tomcat 监控模板(比如 ID 为 8563 的模板),即可看到线程数、GC 次数、响应时间等可视化图表。

11避坑总结(工作中少走弯路)

版本匹配:JDK 和 Tomcat 版本必须对应(比如 Tomcat 8.5 配 JDK 1.8),否则启动报错;权限第一:永远不用 root 运行 Tomcat,目录权限严格控制(读 / 写 / 执行分离);日志优先:任何问题先看日志(catalina.out、访问日志),90% 的答案在日志里;备份配置:修改
server.xml
等核心配置前,先备份(
cp server.xml server.xml.bak
),出错可快速恢复;定期更新:关注 Tomcat 安全漏洞,及时升级到稳定版本,避免用太老的版本(比如 Tomcat 6 已停止维护)。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
安米的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容