news 2026/9/15 2:09:42

Tomcat从入门到生产实践:配置、部署与避坑全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tomcat从入门到生产实践:配置、部署与避坑全解析

做Java服务端开发的人,几乎没有一个绕得过Tomcat。不管是大学里的Servlet作业,还是生产环境里的Spring Boot内嵌容器,Tomcat这个名字你绝对不陌生。但很多人对它的理解停留在“双击startup.bat,浏览器打开8080看到一个猫”的阶段,稍微遇到404、端口占用、JSP编译失败、HTTPS双向认证这类问题就无从下手了。

这篇内容我打算从零完整过一遍Tomcat的核心知识点和实验过程,覆盖安装配置、IDE集成、war包部署、JSP编译机制、server.xml关键配置、双向TLS认证,以及生产环境里的替换方案和避坑经历。无论你是刚入门的学生,还是被项目逼着摸了一遍Tomcat的后端萌新,都能从中拿到能直接落地的东西。我会尽量用实际踩坑的口吻来讲,不写教科书式的废话。

1. 先搞懂Tomcat是什么,以及它到底解决了什么问题

1.1 没有Tomcat的时候,你的Web项目是怎么跑的

很多初学者第一次接触Tomcat,只知道它是一个“服务器”,但完全不清楚它凭什么能把一个Java Web项目跑起来。要理解Tomcat,得先回到Servlet规范这件事上。

浏览器发来的请求是HTTP协议,而Java里写业务逻辑用的是类和方法。想让一个Java类处理HTTP请求,就必须有人做协议解析、请求封装、响应渲染这些脏活。Tomcat干的事情就是这样:它实现了Servlet容器规范,把HTTP请求解析成一个HttpServletRequest对象,交给你的Servlet类处理,再把HttpServletResponse对象转换回HTTP响应发回给浏览器。

换句话说,Tomcat本身不写业务代码,它只是一个“中间人”——你写Servlet,它负责让Servlet跑起来并和浏览器对话。

1.2 下载Tomcat之后,目录里每一层都是干嘛的

安装Tomcat其实没有“安装”这个词,因为是解压即用的绿色软件。下载zip包后解压出来,你会看到binconfliblogstempwebappswork这些目录。新手最容易忽略的是confwork,但恰恰这两个目录最能救命。

  • bin:存放启动和关闭脚本。startup.batshutdown.batcatalina.bat都在这里。Linux下对应的是.sh脚本。
  • conf:Tomcat所有配置文件的所在地。server.xml是最核心的配置文件,端口、连接器、虚拟主机、部署路径全在这。
  • lib:Tomcat运行时依赖的jar包。注意,所有部署到这里的Web应用都能共享这些jar包,但反过来,应用自己WEB-INF/lib下的jar包不会互相干扰。
  • logs:日志目录。catalina.outlocalhost.log这些日志文件是排查问题的第一手资料。
  • webapps:默认部署目录。把war包丢进去,Tomcat启动时会自动解压部署;也有很多人直接把整个Web项目目录放在这里。
  • work:JSP编译产物目录。JSP第一次被访问时会翻译成Java文件再编译成class文件,结果就存在这里。后面我要专门讲怎么用这个目录查看JSP编译后的代码。
  • temp:临时文件目录,不用太关心。

1.3 版本选择是第一个大坑:javax还是jakarta

这点必须单独拎出来说,因为踩坑的人实在太多了。Tomcat 9及以前遵循的是javax.servlet规范,Tomcat 10开始把包名改成了jakarta.servlet

这意味着什么?如果你有一个老项目,代码里写的是import javax.servlet.http.HttpServlet,抛给Tomcat 10跑,启动时你会看到一堆ClassNotFoundException或者NoClassDefFoundError。反过来也一样,用Tomcat 10规范写的新代码跑到Tomcat 9上也会炸。

所以选版本之前,先看清楚你的项目依赖。低版本老项目老老实实用Tomcat 8.5或者9,新项目可以用Tomcat 10/11。另外顺嘴说一句,Tomcat没有32位和64位的区分,它是纯Java程序,真正有位数要求的是你装的那个JDK。

2. 安装、环境变量与启动失败的排查实验

2.1 从JDK版本匹配到环境变量配置

既然是Java程序,安装Tomcat的前提是机器上已经装好了JDK。Tomcat自身对JDK版本有硬性要求,比如Tomcat 9需要JDK 8及以上,Tomcat 10.1需要JDK 11及以上。用过低版本JDK跑高版本Tomcat,报错信息会非常隐晦,经常是Tomcat启动日志里出现UnsupportedClassVersionError

环境变量配置这一块,核心就是JAVA_HOME。很多教程会让你再去配CATALINA_HOME,其实Tomcat启动时最重要的是能找到JAVA_HOME,它通过这个变量去定位java可执行文件。CATALINA_HOME更多的是给IDE或者脚本识别用,配上也更好,省得后面IDEA里还要手动填路径。

Windows上的配置方式:右键“此电脑”->“属性”->“高级系统设置”->“环境变量”,新建JAVA_HOME指向JDK安装目录,并把%JAVA_HOME%\bin追加到Path变量里。配置完了在cmd里敲java -version验证一下,如果显示版本号,说明JDK没问题。

2.2 启动一闪就没的通用排查套路

“双击startup.bat窗口一闪就没了”,这可能是Tomcat新手遇到的最常见问题。这个现象背后通常就三招:环境变量错了、端口被占用了、启动日志报错了但你没看到。

正确做法是不要在桌面双击startup.bat,而是打开cmd,手动切换到Tomcat的bin目录,执行startup.bat。如果环境变量有问题,cmd窗口会直接打出JAVA_HOME相关的错误提示;如果没报错但Tomcat没起来,再执行一次catalina.bat run,这个命令会在前台运行并输出完整启动日志,所有异常堆栈都会直接打在屏幕上。

端口被占用也是高频原因。Tomcat默认使用8080端口,如果本机已经有程序占了8080,启动会报Port 8080 was already in use。Windows下查占用端口的方法:netstat -ano | findstr 8080,看到占用端口的PID后打开任务管理器,在详细信息里找到对应PID把它结束掉,或者改Tomcat端口。Linux下用lsof -i:8080或者ss -lntp | grep 8080来查。

注意:改端口要改两处逻辑相关的地方。server.xml里的HTTP Connector端口是第一处,如果还开了HTTPS或AJP连接器,它们的端口也要确认是否被占用。很多奇怪的启动失败其实都是多个连接器端口里有一个被占了。

2.3 能打开首页但路径不对?检查URL和webapps目录

启动成功之后,浏览器访问http://localhost:8080/会看到Tomcat默认首页,那一只猫的标志性的页面。如果打不开,先确认Tomcat进程是否活着。Linux下排查进程常用ps -ef | grep tomcat,把这个命令作为服务端排查的第一反应,能确认Tomcat到底有没有在运行,以及是用哪个用户、哪条命令启动的。

我见过很多次Tomcat明明启动了,但浏览器就是访问不了,最后排查下来是访问路径问题。Tomcat默认首页映射在根路径/,如果你部署的应用上下文路径是/myapp,访问入口就是http://localhost:8080/myapp/,直接访问根路径当然看不到你的项目。

3. 在IDEA和Eclipse里把Tomcat跑起来

3.1 新版IDEA中配置Tomcat的完整流程

IDEA配置Tomcat这个问题,网上教程五花八门,版本之间差异也挺大。热词里提到的“IDEA 2025.2.6.1”,我虽然没到那个版本,但配置思路是一致的,入口位置可能稍有变化。

以IDEA Ultimate(旗舰版)为例,大体流程是:打开File -> Settings,在Build, Execution, Deployment -> Application Servers中点击加号,选择Tomcat Server,然后指定Tomcat的安装目录。这一步的意义是告诉IDEA:你的机子上有一个Tomcat,在哪个位置。

配置完Application Server之后,还需要给具体项目配置运行方式。点击顶部工具栏的下拉框,选择Edit Configurations,点击左上角加号,往下拉找到Tomcat Server -> Local。在Server页签里选择刚才配好的Tomcat,在Deployment页签里点加号,把你的Web项目以Artifact或者war exploded的方式添加进去。Application context这一栏填的就是访问路径,比如填/myapp,那启动后访问URL就是http://localhost:8080/myapp/

这里多说一句,如果版本较新但你在Edit Configurations里找不到Tomcat Server选项,不要慌,装上Smart Tomcat插件就能解决。这个插件社区版IDEA也能用,配置更简化,只需要填Tomcat目录,然后给每个项目指定部署上下文就行。

3.2 社区版IDEA与Eclipse的配置差异

IDEA社区版不内置Tomcat集成功能,这是很多学生党刚上手时最容易卡住的地方。社区版解决方案有两条路:装Smart Tomcat插件,或者放弃IDE的Tomcat集成,直接用Maven的cargo插件来启停Tomcat。

就我个人经验,社区版+插件方案最省心。装好插件后在Run Configuration里选择Smart Tomcat,配置三个关键点:Tomcat Server路径、上下文路径、要部署的模块。相比旗舰版的繁琐配置,这个方案反而更简单。

Eclipse的配置逻辑和IDEA完全不同,它是通过Servers视图来管理Tomcat的。在Window -> Preferences -> Server -> Runtime Environments里添加Tomcat运行环境,然后在Servers视图里右键新建一个Server。特别注意:Eclipse默认会把项目部署到工作空间临时目录里,而不是Tomcat安装目录的webapps下。想让它部署到真目录,双击Server实例,勾选Use Tomcat installation,再把Deploy Path改成webapps

3.3 实验:查看JSP编译后的Java类

JSP本质上就是一个Servlet,只不过它以.jsp后缀保存。当浏览器第一次访问某个JSP页面时,Tomcat内部的Jasper引擎会把JSP翻译成一个Java源文件,再编译成class文件。翻译出来的Java代码其实就是一个继承HttpServlet的类,你写在JSP里的<%%>脚本会被原样塞进_jspService方法里。

那么问题来了,这个编译产物在哪?答案在Tomcat的work目录。默认路径是work/Catalina/localhost/<应用上下文>/org/apache/jsp/,文件名格式和JSP路径对应,比如index.jsp就会生成index_jsp.javaindex_jsp.class

如果你用的是IDEA/Eclipse启动Tomcat,work目录的位置可能不在Tomcat安装目录下。比如Eclipse会把它藏在当前工作空间的.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work目录下;IDEA则可能存放在项目根目录下的out或者target临时目录里。找不到的时候,最笨但有效的方法是在项目里全局搜索类似*_jsp.java的文件。

打开编译后的Java文件,你能清晰看到JSP里静态的HTML内容都变成了out.write()方法,动态的Java片段原样保留,这就是JSP和Servlet在底层上的关系。想调试JSP里某个变量值,又不想在页面打印,可以直接在这个Java文件对应的行号打断点。

4. 部署Web项目:war包、目录映射和404排查

4.1 三种部署方式对比,各有什么坑

Tomcat部署Web项目可以分成三种方式,每种都有自己的适用场景。

第一种是直接把项目目录或war包丢进webapps目录。这是最朴素的方式,适合测试环境。war包会被Tomcat自动解压成同名目录,然后以/war包名作为访问路径。坑在于:改动后需要重启Tomcat才能生效,对于频繁迭代的开发阶段非常不友好。

第二种是通过Tomcat Manager来热部署。启动Tomcat后访问http://localhost:8080/manager/html,输入配置好的管理员账号密码,在页面上传war包或者指定路径部署。这种方式适合在不重启Tomcat的前提下快速更新应用,但默认情况下Manager需要额外配置conf/tomcat-users.xml里的用户角色,不配置你连不上。

第三种是IDE集成的部署方式。IDEA和Eclipse在启动调试时会自动部署项目,并且支持热更新。开发阶段强烈建议用这种方式,改完Java代码重新编译就可以增量更新,效率高很多。

4.2 war包手工部署的完整过程

从IDEA里构建war包很简单,前提是项目里配置好war或者war exploded类型的artifact。Build -> Build Artifacts -> All Artifacts -> Build,构建完成后在out/artifacts目录下就能看到war包。如果你的项目是Maven工程,更标准的做法是执行mvn clean package,war包生成在target目录下。

拿到war包之后,Linux服务器上的部署流程一般是这样的:

# 停掉Tomcat,避免文件锁导致解压失败 sh /opt/tomcat/bin/shutdown.sh # 备份旧包,养成好习惯 cp /opt/tomcat/webapps/myapp.war /backup/myapp.war.$(date +%Y%m%d%H%M%S) # 删除旧的应用目录和war包 rm -rf /opt/tomcat/webapps/myapp /opt/tomcat/webapps/myapp.war # 上传新war包到webapps目录 # 假设你已经用scp/rz把war包传到了/opt/tomcat/webapps/下 # 启动Tomcat sh /opt/tomcat/bin/startup.sh # 查看启动日志 tail -f /opt/tomcat/logs/catalina.out

部署之后访问不了不要急着怀疑代码,先看catalina.out日志。日志一旦打出Deployment of web application archive [myapp.war] has finished,说明部署成功,访问路径就是http://服务器IP:8080/myapp/

4.3 启动后访问404的排查清单

展开谈谈“Tomcat启动后访问404”这个高频问题。404不是Tomcat没起来,而是请求路径无法匹配到对应的应用和资源。我总结了一份排查顺序,每次遇到404都按这个顺序来:

  1. 先确认访问端口对不对。从浏览器地址栏到server.xml里的Connector端口是否一致。
  2. 确认应用上下文路径。部署后的应用路径是/myapp还是/,访问根路径和访问具体应用路径不是一回事。
  3. 确认war包解压是否成功。看webapps目录下有没有生成对应的应用目录。
  4. 查看logs/localhost.日期.log,这个日志专门记录Tomcat启动过程中加载Web应用的情况,里面会写Deployment of web application archive has failed之类的错误原因。
  5. 确认应用里WEB-INF/web.xml配置的servlet-mapping是否匹配访问地址,以及是否有Spring MVC这类框架的前置控制器接管了所有路径。
  6. 查看应用自己日志中是否报错导致启动失败。很多404是因为项目依赖的jar包缺失导致Servlet没有注册成功。

提示:IDEA里部署项目后访问404,八成是Application context填写不对。IDEA的Tomcat配置里,Deployment页签下每个artifact都有一个Application context,它决定访问前缀,填成/就是根路径访问,填成/demo就得到http://localhost:8080/demo/去访问。

5. 绕不过去的server.xml:端口、HTTPS与双向认证

5.1 从一份默认配置说起

server.xml是Tomcat配置文件的灵魂。打开它,默认的骨架结构大概是这样的:最外层是<Server>节点,指定了端口8005和关闭指令;里面有一个<Service>节点,名为Catalina;再往里是<Connector><Engine><Host><Context>这些组件。

很多新手看不懂这一堆嵌套的XML,我打个比方:Server是一个完整的Tomcat实例,Service是这个实例对外提供的服务,Connector是服务接电话的接线员,Engine是处理电话的总机,Host是按域名区分租户的租房合同,Context是租户房间里具体住的应用。

<Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps"> <Context path="/myapp" docBase="/data/myapp" reloadable="true"/> </Host> </Engine> </Service> </Server>

5.2 端口8005和redirectPort是什么意思

这里专门解释一下热词里提到的<Server port="8005" shutdown="SHUTDOWN">。8005端口是Tomcat专门用来接收关闭指令的端口,shutdown属性的值SHUTDOWN就是关闭密码。当你在命令行执行shutdown.sh时,脚本会向这个端口发送字符串SHUTDOWN,Tomcat收到后执行关闭流程。

这个端口是安全隐患高发区。如果服务器上有防火墙没封掉8005,别人可以发送一个SHUTDOWN指令直接把你的Tomcat干掉。生产环境强烈建议改成不容易猜的随机字符串,或者直接把port改成-1来禁用这个端口,改为用进程管理工具(比如systemd)来控制启停。

redirectPort是另一个高频疑惑点。当请求使用HTTP访问某个资源,而这个资源被配置为需要HTTPS安全连接时,Tomcat无法用当前HTTP连接器继续处理,就会把请求重定向到redirectPort指定的端口。所以redirectPort="8443"是在告诉Tomcat:当遇到HTTP请求需要转HTTPS时,请把它转到8443端口(HTTPS Connector所在端口)。没有配置HTTPS Connector的情况下,即使设了redirectPort,重定向过去也是白搭,连接不上。

5.3 实验:Tomcat作为客户端实现MTLS双向认证

双向TLS认证,简单说就是客户端验证服务器的证书,同时服务器也验证客户端的证书,双方都持有对方的信任凭证,任何一方不信任,通信就建立不了。这在金融、政务等对安全等级要求高的系统里非常常见。热词里提到“Tomcat作为客户端请求服务端实现MTLS双向认证”,说明大家不仅关心服务端怎么配,更关心调用方怎么配。

先交代证书生成的思路。用JDK自带的keytool命令就能完成。假设已经有一台CA服务器签发好了服务端证书和客户端证书,核心步骤是:把服务端证书加入客户端的信任库,把客户端证书密钥放入客户端的密钥库。

Tomcat作为客户端,本质就是发起HTTPS请求的Java程序,需要用javax.net.ssl.keyStorejavax.net.ssl.trustStore这两个系统属性来指定客户端密钥库和信任库。代码层面最简单的方式是在启动JVM时加参数:

-Djavax.net.ssl.keyStore=/path/to/client.p12 -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit

如果走的Spring Boot项目,可以用RestTemplate加自定义SSLContext

KeyStore keyStore = KeyStore.getInstance("PKCS12"); try (InputStream in = new FileInputStream("/path/to/client.p12")) { keyStore.load(in, "changeit".toCharArray()); } KeyStore trustStore = KeyStore.getInstance("JKS"); try (InputStream in = new FileInputStream("/path/to/truststore.jks")) { trustStore.load(in, "changeit".toCharArray()); } KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keyStore, "changeit".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); CloseableHttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); HttpGet get = new HttpGet("https://server.example.com/api"); try (CloseableHttpResponse response = httpClient.execute(get)) { // 处理响应 }

如果只是想用命令行验证服务端的双向TLS是否配置成功,用curl最方便:

curl --cert /path/to/client-cert.pem --key /path/to/client-key.pem \ --cacert /path/to/ca-cert.pem \ https://server.example.com/api

注意:双向TLS调试时最闹心的就是证书信任链不完整。客户端信任库只放服务端证书还不够,如果服务端证书是由中间CA签发的,那么中间CA证书也得放进信任链。反过来服务端信任客户端证书时也一样。这类问题报错通常是PKIX path building failed,说明证书链没配完整。

服务端让Tomcat启用双向TLS,核心是改server.xml里HTTPS Connector的配置:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="200" scheme="https" secure="true" clientAuth="true" keystoreFile="/path/to/server.p12" keystorePass="changeit" keystoreType="PKCS12" truststoreFile="/path/to/truststore.jks" truststorePass="changeit" truststoreType="JKS" />

clientAuth="true"表示强制要求客户端提供证书,这是双向认证和普通HTTPS最核心的区别。

5.4 Tomcat生产环境的核心调优参数

server.xml里Connector节点上有几个关键参数,直接影响生产环境的表现。maxThreads控制最大工作线程数,默认200,高并发场景一般调到400到800,具体要看机器核数和业务耗时。acceptCount是等待队列长度,当线程满时会排在队列里,默认100,可以适当调大。connectionTimeout表示建立连接的超时时间,默认20000毫秒。

JVM调优则是启动脚本catalina.shJAVA_OPTS的事。生产机内存别交给默认值,至少显式指定堆大小:

JAVA_OPTS="-Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"

从实用角度说,堆大小最大值和最小值设成一致,避免运行期动态扩容带来性能抖动。这些参数没有标准答案,需要结合压测结果不断调整。

6. 替换与混淆:Spring Boot内嵌Tomcat、宝兰德BES和Allatori的坑

6.1 Spring Boot应用的“内置Tomcat”还能换掉吗

Spring Boot项目在spring-boot-starter-web里默认内嵌了Tomcat,所以你可以用java -jar直接跑Web服务,不用单独部署外部Tomcat。但这不等于你的代码耦合死了Tomcat,它默认可以换容器。pom.xml里排除Tomcat,然后引入其他的Servlet容器依赖即可:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>

排除之后,如果你的应用还需要Servlet容器,可以引入Jetty或者Undertow。这里有个常见误区:如果只是把内嵌Tomcat排除掉,但不提供替换容器,应用将无法处理HTTP请求,嵌入的WebServer启动时会直接失败。

如果要用外部Tomcat部署Spring Boot项目,做法是:打包方式改成war,并在启动类里继承SpringBootServletInitializer并重写configure方法:

@SpringBootApplication public class DemoApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(DemoApplication.class); } }

这样打包出来的war包丢到Tomcat的webapps下,Tomcat会自动启动Spring Boot应用。

6.2 宝兰德BES替换Tomcat时需要注意什么

宝兰德BES是一个国产企业级中间件,很多政企项目出于信创要求,需要把Tomcat换成BES。这个话题在业内讨论度很高。从技术角度讲,BES Web Server遵循Java EE规范,支持Servlet规范,所以理论上大部分war包换过去能直接运行。

替换过程核心是三件事:第一,把项目的war包通过BES管理控制台部署,而不是扔进Tomcat的webapps目录。第二,BES的端口配置和Tomcat不同,BES Web Server默认端口不是8080,具体以安装后conf目录下域配置里实际端口为准。第三,Spring Boot项目要换成BES跑,需要排除内嵌Tomcat依赖,并打包成war,和前面说的外部Tomcat部署套路一致,关键是在pom.xml里把容器依赖设置为provided,这样war包里不会带着Tomcat相关的jar包,避免和BES自身的Servlet实现冲突。

经验之谈:从Tomcat迁移到BES之后,最容易炸的是cookie加密策略、Session机制、文件上传大小限制、字符集编码这些和容器行为强相关的配置。部署完成后第一件事不是测业务功能,而是先把登录、文件下载、跨域请求这些基础能力过一遍,能快点暴露容器兼容性问题。

6.3 Allatori混淆传统Tomcat Web工程,三个必踩的坑

热词里出现“Allatori 混淆 传统 Tomcat web 工程”,说明不少同学正在处理代码混淆。Allatori是一个Java混淆器,它能把class文件里的类名、方法名、字段名替换成无意义的名字,加大逆向阅读的难度。但传统Tomcat Web工程做混淆,坑是真不少。

第一个坑是混淆Servlet类导致映射失效。web.xml里写的是<servlet-class>com.example.LoginServlet</servlet-class>,如果你把com.example.LoginServlet这个类改了名字,容器的映射建立不起来,请求直接404。解决思路是在Allatori配置里保留要对外暴露的类名,一般通过keep节点设置包名或类名白名单。

第二个坑是混淆掉依赖jar里的方法。如果你的工程用了Spring这类重量级框架,混淆器容易把框架里依赖的反射调用搞乱,运行时抛NoSuchMethodErrorClassNotFoundException。这种问题排查很痛苦,因为日志里的类名已经被改了。稳妥的办法是只混淆自己的业务代码,框架代码保持原样。

第三个坑是JSP和静态资源无法混淆。JSP页面里的<%@ page import="com.example.DemoBean"%>是字符串引用,混淆器不会自动去改JSP里的文字。如果DemoBean被改了名,JSP里引用就会找不到类。所以混淆前后必须做一遍全量回归,尤其是页面请求和带Java代码的JSP页面。

6.4 一套遇到问题就能用的排查命令

最后分享几个日常排查Tomcat问题时的高频命令,都是实测下来用的最多的。放在一个清单里,遇到问题按顺序来。

# 1. 看进程还在不在 ps -ef | grep tomcat # 2. 看端口在不在监听 # Linux ss -lntp | grep 8080 lsof -i:8080 # Windows netstat -ano | findstr 8080 # 3. 看启动日志 tail -100f /opt/tomcat/logs/catalina.out # 4. 看应用部署日志 tail -100f /opt/tomcat/logs/localhost.$(date +%Y-%m-%d).log # 5. 发起请求测试,观察响应码 curl -v http://localhost:8080/myapp/ # 6. 抓线程快照,排查线程卡死 jstack $(pgrep -f "bootstrap.jar" | head -1) > /tmp/jstack.log # 7. 抓内存快照,排查OOM jmap -dump:format=b,file=/tmp/app.hprof $(pgrep -f "bootstrap.jar" | head -1)

这里额外提醒一句:jstackjmap对线上环境影响较大,尤其是jmap会导致JVM停顿,高并发业务高峰期慎用。真要排查问题也建议先和团队确认,别闷头就执行。

写在最后的个人经验

Tomcat这个玩意,说简单也简单,下载解压就能跑;说复杂也复杂,生产环境里各种连接器配置、类加载器冲突、证书信任链问题,每个都能把人折磨到怀疑人生。我自己的体会是,遇到Tomcat问题不要急着瞎试,先看日志、再查端口、最后看配置,按这个顺序来,90%的问题能快速定位。还有一点要养成习惯:每次部署前备份好旧的war包和配置文件,改server.xml前先复制一份,这个习惯救过我无数次。Tomcat的运行机制搞明白了,后面接触任何Servlet容器(比如Jetty、Undertow、宝兰德)都是触类旁通的事。希望这篇内容对你有用,有问题欢迎在实际操作后回来对照排查清单再走一遍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 2:08:48

计量设备UART/SPI调试实战:低功耗高可靠通信避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 2:07:42

本科生必备:10大降AI率工具评测与使用指南

1. 项目概述&#xff1a;为什么本科生需要关注降AI率工具&#xff1f;2023年被称为AI内容爆发元年&#xff0c;但随之而来的是学术界和职场对AI生成内容的警惕。最近半年&#xff0c;超过60%的985高校明确将"AI率"纳入论文检测指标&#xff0c;部分企业HR也开始使用A…

作者头像 李华
网站建设 2026/9/15 2:07:29

DOTA航拍目标检测实战:基于YOLOv3的完整训练与优化指南

简介&#xff1a;基于DOTA数据集的YOLO训练资源包&#xff0c;面向目标检测与计算机视觉方向的课程设计、期末大作业及毕业设计。整套资源涵盖Python源码、网络配置文件、数据映射文件、训练脚本及说明文档&#xff0c;共18个文件&#xff0c;压缩包约517KB&#xff0c;包括YOL…

作者头像 李华
网站建设 2026/9/15 2:06:39

从纸质巡检到AR数字孪生:数据中心机房巡检的智能化实践

从纸质巡检表到AR眼睛里的数字孪生&#xff1a;我的一次AR机房巡检实践复盘先说个场景。去年某个周末凌晨&#xff0c;数据中心二楼列头柜告警&#xff0c;值班同事一路小跑过去&#xff0c;手里攥着一沓A4纸巡检表和一支笔。他对着机柜顶部标签一个个核对&#xff0c;又蹲下去…

作者头像 李华
网站建设 2026/9/15 2:04:54

基于YOLOv8的道路裂缝识别系统:从数据集准备到模型训练与部署

简介&#xff1a;这套基于YOLOv8的交通道路裂缝识别系统&#xff0c;面向计算机视觉、人工智能等专业的学生和开发者&#xff0c;可快速搭建路面裂缝检测演示环境&#xff0c;适用于毕业设计、课程设计或项目初期立项。包内共8个文件&#xff0c;包括3个Python脚本&#xff08;…

作者头像 李华