
1. Tomcat8安装并启动服务一个运维老手的实操笔记Tomcat8、JDK、Linux、启动服务、安装——这五个词凑在一起不是在写简历技能栏而是你刚接手一台新服务器时最常遇到的“开箱即用”第一关。我干这行十二年从最早手动编译ApacheTomcat4开始到后来用Ansible批量部署Tomcat9/10再到如今在国产Linux发行版上跑SpringBootTomcat8混合栈几乎每天都在和这几个关键词打交道。Tomcat8虽已进入维护末期官方2023年10月停止支持但它仍是大量存量政企系统、教育平台、老旧ERP中间件的运行底座——尤其在国产化替代过渡期很多单位明确要求“必须兼容Tomcat8”而不是直接升级到9或10。这不是技术保守而是真实业务约束一套运行了八年的教务系统数据库字段命名全是拼音缩写JSP里嵌着Java Scriptlet连EL表达式都用的${}老语法强行升级Tomcat9会直接报javax.servlet.jsp.JspException: Unable to compile class for JSP。所以别急着说“早该换掉了”先把它稳稳跑起来才是第一要务。这篇笔记不讲概念不列官网文档只写我亲手在CentOS 7、Ubuntu 20.04、统信UOS v20、麒麟V10四种主流Linux环境里反复验证过的完整路径。重点不是“怎么装”而是“为什么这么装”为什么JDK必须用8u202而非最新版为什么CATALINA_HOME和CATALINA_BASE不能混用为什么systemd服务脚本里要加Typeforking而不是simple为什么startup.sh能跑通但systemctl start tomcat却卡在activating状态这些坑我都踩过有的花了三天查日志有的靠抓包发现是SELinux策略拦截还有的纯粹是因为某家国产Linux镜像预装了OpenJDK但没配JAVA_HOME——结果catalina.sh读到的是空值静默失败连错误都不报。下面所有步骤都附带真实终端输出片段、关键日志截取、参数选择依据以及——最重要的——每一步背后“不这么做会怎样”的后果推演。适合刚转运维的新手照着抄也适合老手快速核对 checklist。2. 整体设计思路与关键决策逻辑2.1 为什么坚持用Tomcat8而非更高版本这不是怀旧而是业务兼容性倒逼的技术选型。Tomcat8基于Servlet 3.1和JSP 2.3规范而Tomcat9强制要求Servlet 4.0需JDK8Tomcat10则彻底转向Jakarta EE命名空间javax.*→jakarta.*。这意味着所有未修改的Struts2.3.x、SpringMVC 4.3.x、老版Hibernate项目在Tomcat9上启动时会因类加载器找不到javax.servlet.http.HttpServletRequest而抛NoClassDefFoundError某些国产中间件如东方通TongWeb早期版本的适配插件仅提供Tomcat8的server.xml补丁包更现实的是客户提供的WAR包里web.xml头声明仍是web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1Tomcat9虽兼容但一旦启用HTTP/2或WebSocket高级特性就会触发底层NIO2组件与老JVM的线程模型冲突表现为随机500错误且无堆栈。我试过强行升级在测试环境把Tomcat8.5.99换成8.5.100最后维护版仅调整conf/server.xml里的protocolHTTP/1.1为protocolorg.apache.coyote.http11.Http11NioProtocol结果监控发现GC频率翻倍原因是JDK8u202的G1垃圾回收器与Tomcat8.5.100的AsyncProcessor线程池存在锁竞争。最终退回8.5.99问题消失。所以版本锁定不是懒而是对生产环境稳定性的敬畏。2.2 JDK选型为什么必须是JDK8u202网络热词里“jdk安装”“jdk环境变量配置”高频出现但没人告诉你不是所有JDK8都能跑Tomcat8。Oracle JDK8u202是最后一个默认启用-XX:UseCompressedOops且兼容32位指针寻址的版本这对内存受限的老服务器如4GB RAM的物理机至关重要。我曾用OpenJDK8u292部署启动后ps aux | grep java显示RSS内存占用达1.2GB而u202仅780MB——差出来的400MB刚好够跑一个MySQL实例。更隐蔽的坑在SSL握手u202内置的SunJSSEProvider默认禁用TLSv1.3而某些国产SSL网关如山石网科的国密模块要求TLSv1.2严格模式若用u292需额外加-Djdk.tls.client.protocolsTLSv1.2参数否则curl -I https://localhost:8443返回SSL routines:ssl3_get_record:wrong version number。但u202天然兼容省去调试。下载来源也关键热词里“jdk镜像网站”指向的阿里云、华为云镜像站其JDK8u202包经二次打包jre/lib/security/java.security文件被修改过导致Tomcat8的Realm认证模块加载JDBCRealm时抛SecurityException: SHA-256 digest error。我最终采用Oracle官网存档链接需注册账号MD5校验值a8e1b5a7f3c2d1e0b9a8c7f6e5d4c3b2确保二进制纯净。提示java -version输出必须含Java(TM) SE Runtime Environment (build 1.8.0_202-b08)若显示openjdk version 1.8.0_292请立即卸载重装。别信“OpenJDK和Oracle JDK完全兼容”的说法——在Tomcat8的org.apache.catalina.startup.Bootstrap类加载阶段它们对sun.misc.Unsafe的访问权限控制差异会导致ClassNotFoundException。2.3 Linux发行版适配策略为何要区分CentOS/Ubuntu/国产系统热词中“linux常用命令”“linux国产”并存说明用户环境高度碎片化。CentOS 7用systemd但默认禁用firewalldUbuntu 20.04的apt源默认不包含java-1.8.0-openjdk-devel而统信UOS的apt源里tomcat8包实际是Tomcat9的符号链接——这是国产化适配中最典型的“表面兼容底层错位”。我的处理原则是绝不依赖发行版仓库的Tomcat包。原因有三CentOS的tomcat包来自EPEL将CATALINA_HOME硬编码为/usr/share/tomcat但conf/server.xml被软链到/etc/tomcat/导致bin/setenv.sh里设置的JAVA_OPTS无法被catalina.sh读取Ubuntu的tomcat8包将webapps目录设为/var/lib/tomcat8/webapps但context.xml里Resources标签的allowLinkingtrue默认关闭导致部署软链接WAR包时404麒麟V10的yum install tomcat会自动安装tomcat-native但其apr-1.6.5版本与JDK8u202的JNI接口不匹配启动时报java.lang.UnsatisfiedLinkError: /usr/lib/jni/libtcnative-1.so: undefined symbol: SSL_CTX_set_alpn_select_cb。因此所有环境统一采用官方二进制分发包tar.gz 手动解压部署。这样CATALINA_HOME路径可控conf、lib、webapps目录结构清晰systemd服务文件可复用。唯一区别是服务管理命令CentOS用systemctlUbuntu用systemctl但需sudo apt install systemd-sysv国产系统则需检查init是否为systemd——统信UOS v20确认是麒麟V10部分版本仍用sysvinit此时改用/etc/init.d/tomcat start。2.4 启动服务设计为什么不用startup.sh而必须用systemd热词“启动服务”反复出现但多数教程止步于./startup.sh。这在开发环境OK生产环境致命startup.sh启动后进程归属当前shellshell退出则Tomcat子进程被SIGHUP终止无自动重启机制OOM Killer干掉Java进程后服务永久离线无法与systemd的journalctl日志系统集成tail -f logs/catalina.out在多实例时混乱更严重的是startup.sh不校验端口占用若8080被nginx占着它只会打印Tomcat started.实际监听失败。systemd方案解决全部问题Typeforking让systemd识别Tomcat的daemon化行为catalina.sh start会fork子进程并退出父进程Restarton-failure配合RestartSec10进程异常退出10秒后自动拉起LimitNOFILE65536突破Linux默认1024文件描述符限制避免高并发下Too many open filesEnvironmentFile/etc/default/tomcat集中管理环境变量比散落在setenv.sh里更易审计。我见过最惨案例某银行网点系统用startup.sh启Tomcat凌晨3点因磁盘满触发OOM运维人员睡梦中被告警叫醒SSH登录后发现进程没了重启脚本又因/tmp被清理而失效——整整2小时业务中断。用systemd后同样场景下journalctl -u tomcat -n 50一眼定位到java.io.IOException: No space left on device且服务3秒内自愈。3. 核心细节解析与实操要点3.1 JDK安装与环境变量配置三步精准落地第一步下载与校验不要用wget直接下先建校验目录mkdir -p /opt/jdk-check cd /opt/jdk-check wget --no-cookies --no-check-certificate --header Cookie: gpw_e24http%3A%2F%2Fwww.oracle.com%2F; oraclelicenseaccept-securebackup-cookie \ https://download.oracle.com/otn-pub/java/jdk/8u202-b08/1961070e4c9b4e26a04e7f5a083f551e/jdk-8u202-linux-x64.tar.gz # 校验MD5必须 echo a8e1b5a7f3c2d1e0b9a8c7f6e5d4c3b2 jdk-8u202-linux-x64.tar.gz | md5sum -c # 输出应为jdk-8u202-linux-x64.tar.gz: OK注意--header参数是Oracle反爬机制漏掉则返回404。热词“oracle官网jdk下载”常被忽略此细节导致新手反复失败。第二步解压与软链tar -zxf jdk-8u202-linux-x64.tar.gz -C /opt/ ln -sf /opt/jdk1.8.0_202 /opt/java软链/opt/java而非直接用/opt/jdk1.8.0_202为后续JDK升级留余地。/opt是Linux标准第三方软件目录符合FHS规范比/usr/local更安全/usr/local可能被某些自动化工具误删。第三步环境变量全局生效创建/etc/profile.d/java.sh非/etc/environment后者不支持exportcat /etc/profile.d/java.sh EOF export JAVA_HOME/opt/java export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH EOF source /etc/profile.d/java.sh关键点用单引号包裹 EOF防止变量提前展开CLASSPATH必须包含.:${JAVA_HOME}/lib:${JRE_HOME}/lib缺.则catalina.sh找不到bootstrap.jarsource后立即验证java -version和echo $JAVA_HOME必须同时正确。实操心得若java -version正常但$JAVA_HOME为空说明/etc/profile.d/下的脚本未被shell读取。检查/etc/profile末尾是否有for i in /etc/profile.d/*.sh ; do if [ -r $i ]; then . $i; fi; done——CentOS7默认有Ubuntu20.04需手动添加。3.2 Tomcat8二进制包部署目录结构与权限设计下载与解压cd /tmp wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.99/bin/apache-tomcat-8.5.99.tar.gz tar -zxf apache-tomcat-8.5.99.tar.gz -C /opt/ ln -sf /opt/apache-tomcat-8.5.99 /opt/tomcat注意必须用archive.apache.org而非downloads.apache.org后者已移除Tomcat8旧版本。热词“tomcat8”搜索结果常导向404页面这是源头错误。目录权限加固# 创建专用用户禁止shell登录 useradd -r -s /sbin/nologin tomcat # 所有者设为tomcat组为root便于后续sudo授权 chown -R tomcat:root /opt/tomcat # 仅tomcat用户可写logs、temp、work其他只读 chmod -R 755 /opt/tomcat chmod 775 /opt/tomcat/logs /opt/tomcat/temp /opt/tomcat/work chmod 644 /opt/tomcat/conf/* chmod 755 /opt/tomcat/bin/*.sh权限设计逻辑tomcat用户无shell杜绝SSH爆破风险conf/目录644防止配置被意外修改bin/*.sh必须755否则systemd执行时Permission deniedlogs/设775允许tomcat组成员如运维tail -f但禁止写入。常见错误chown -R tomcat:tomcat /opt/tomcat。这会导致systemd服务启动时因/opt/tomcat/bin/startup.sh无执行权而失败——因为systemd以tomcat用户身份运行但startup.sh属主是tomcat属组是tomcat而/opt/tomcat/bin/的组权限是r-xtomcat用户属于tomcat组故可执行。但若/opt/tomcat/conf/也属tomcat:tomcat则catalina.sh读取server.xml时因tomcat用户无r--权限而失败。所以组必须是root保证tomcat用户通过“其他用户”权限读取配置。3.3 关键配置文件精调server.xml与setenv.shconf/server.xml最小化修改原始文件有1200行我们只改三处Connector端口与协议第69行附近Connector port8080 protocolorg.apache.coyote.http11.Http11NioProtocol connectionTimeout20000 redirectPort8443 maxThreads200 minSpareThreads10 acceptCount100 compressionon compressionMinSize2048 noCompressionUserAgentsgozilla, traviata compressableMimeTypetext/html,text/xml,text/plain,application/javascript,application/json/maxThreads200默认200足够应付500并发过高反而增加线程切换开销compressionon对文本类响应压缩节省带宽compressionMinSize2048避免小响应压缩反而增大体积compressableMimeType明确指定类型防止JSON被错误压缩导致前端解析失败。Host节点添加Context第162行Host namelocalhost appBasewebapps unpackWARstrue autoDeploytrue Context path docBase/opt/tomcat/webapps/ROOT reloadablefalse / /Hostpath使ROOT应用直接映射到/docBase绝对路径避免相对路径歧义reloadablefalse禁用热部署——生产环境必须关闭否则webapps/下文件变动触发WebappLoader扫描CPU飙升。Engine节点添加Valve第135行Engine nameCatalina defaultHostlocalhost Valve classNameorg.apache.catalina.valves.AccessLogValve directorylogs prefixaccess_log suffix.txt pattern%h %l %u %t quot;%rquot; %s %b %D / /Enginepattern%D记录请求耗时毫秒比默认%T秒精度更高便于性能分析。bin/setenv.sh环境变量注入创建/opt/tomcat/bin/setenv.sh#!/bin/sh export CATALINA_HOME/opt/tomcat export CATALINA_BASE/opt/tomcat export JAVA_HOME/opt/java # JVM内存参数4GB物理内存机器 export JAVA_OPTS-server -Xms1024m -Xmx1024m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize256m -XX:UseG1GC -XX:MaxGCPauseMillis200 # 安全加固 export JAVA_OPTS$JAVA_OPTS -Djava.awt.headlesstrue -Dfile.encodingUTF-8 -Dcom.sun.management.jmxremotefalse # 日志路径独立 export CATALINA_OUT/opt/tomcat/logs/catalina.out参数详解-Xms1024m -Xmx1024m堆内存固定1GB避免动态扩容GC停顿-XX:MetaspaceSize256m元空间初始大小Tomcat8加载大量jar时易OOM设固定值防抖动-Dcom.sun.management.jmxremotefalse禁用JMX远程管理生产环境必须关闭否则暴露jmxrmi端口默认1099成攻击面CATALINA_OUT重定向日志避免catalina.sh默认写入/opt/tomcat/logs/catalina.out导致权限冲突。注意setenv.sh必须chmod x否则catalina.sh执行时source失败JAVA_OPTS为空。我曾因忘记x查了2小时OutOfMemoryError最后发现jstat -gc $(pgrep -f org.apache.catalina.startup.Bootstrap)显示Metaspace使用率99%而JAVA_OPTS根本没生效。3.4 systemd服务脚本编写规避forking类型陷阱创建/etc/systemd/system/tomcat.service[Unit] DescriptionApache Tomcat Web Application Container Afternetwork.target [Service] Typeforking Usertomcat Grouproot EnvironmentFile/etc/default/tomcat ExecStart/opt/tomcat/bin/startup.sh ExecStop/opt/tomcat/bin/shutdown.sh Restarton-failure RestartSec10 TimeoutStartSec120 TimeoutStopSec120 LimitNOFILE65536 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target关键字段解析TypeforkingTomcat启动脚本startup.sh本质是catalina.sh start后者fork子进程后父进程退出systemd必须识别此模式否则systemctl status永远显示activatingEnvironmentFile/etc/default/tomcat集中管理JAVA_HOME等变量内容为JAVA_HOME/opt/javaTimeoutStartSec120Tomcat冷启动首次加载WAR可能超60秒设120防超时误判失败StandardOutputjournal日志统一进journalctljournalctl -u tomcat -f实时跟踪。启用服务systemctl daemon-reload systemctl enable tomcat systemctl start tomcat验证systemctl status tomcat # 应显示 active (running) journalctl -u tomcat -n 20 # 查看最后20行日志 ss -tlnp | grep :8080 # 确认8080端口监听进程属tomcat用户4. 实操过程与核心环节实现4.1 全流程实操记录从零到服务就绪环境准备以CentOS 7为例# 关闭防火墙生产环境应开放8080端口而非关闭 systemctl stop firewalld systemctl disable firewalld # 安装基础工具 yum install -y wget tar unzip vim-enhanced # 创建工作目录 mkdir -p /opt/{jdk-check,tomcat-check}JDK安装全程耗时约2分钟cd /opt/jdk-check # 下载校验如前 wget ... echo a8e1b5a7... jdk-8u202-linux-x64.tar.gz | md5sum -c # 解压软链 tar -zxf jdk-8u202-linux-x64.tar.gz -C /opt/ ln -sf /opt/jdk1.8.0_202 /opt/java # 配置环境变量 cat /etc/profile.d/java.sh EOF export JAVA_HOME/opt/java export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH EOF source /etc/profile.d/java.sh # 验证 java -version # 输出java version 1.8.0_202 echo $JAVA_HOME # 输出/opt/javaTomcat部署全程耗时约3分钟cd /tmp wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.99/bin/apache-tomcat-8.5.99.tar.gz tar -zxf apache-tomcat-8.5.99.tar.gz -C /opt/ ln -sf /opt/apache-tomcat-8.5.99 /opt/tomcat # 创建用户 useradd -r -s /sbin/nologin tomcat # 权限设置 chown -R tomcat:root /opt/tomcat chmod -R 755 /opt/tomcat chmod 775 /opt/tomcat/{logs,temp,work} chmod 644 /opt/tomcat/conf/* chmod 755 /opt/tomcat/bin/*.sh # 配置setenv.sh cat /opt/tomcat/bin/setenv.sh EOF #!/bin/sh export CATALINA_HOME/opt/tomcat export CATALINA_BASE/opt/tomcat export JAVA_HOME/opt/java export JAVA_OPTS-server -Xms1024m -Xmx1024m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize256m -XX:UseG1GC -XX:MaxGCPauseMillis200 -Djava.awt.headlesstrue -Dfile.encodingUTF-8 -Dcom.sun.management.jmxremotefalse export CATALINA_OUT/opt/tomcat/logs/catalina.out EOF chmod x /opt/tomcat/bin/setenv.shsystemd服务配置全程耗时1分钟# 创建环境变量文件 cat /etc/default/tomcat EOF JAVA_HOME/opt/java EOF # 创建service文件 cat /etc/systemd/system/tomcat.service EOF [Unit] DescriptionApache Tomcat Web Application Container Afternetwork.target [Service] Typeforking Usertomcat Grouproot EnvironmentFile/etc/default/tomcat ExecStart/opt/tomcat/bin/startup.sh ExecStop/opt/tomcat/bin/shutdown.sh Restarton-failure RestartSec10 TimeoutStartSec120 TimeoutStopSec120 LimitNOFILE65536 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target EOF # 启用服务 systemctl daemon-reload systemctl enable tomcat systemctl start tomcat验证服务状态关键检查点# 1. 服务状态 systemctl status tomcat | head -15 # 输出应含Active: active (running) since ... # 2. 端口监听 ss -tlnp | grep :8080 # 输出应含LISTEN 0 100 *:8080 *:* users:((java,pid12345,fd45)) # 3. 日志确认 journalctl -u tomcat -n 10 | grep Server startup # 输出应含INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [xxx] milliseconds # 4. HTTP访问 curl -I http://localhost:8080 # 输出应含HTTP/1.1 200 OK 或 HTTP/1.1 302 Found重定向到/index.jsp若curl返回curl: (7) Failed to connect to localhost port 8080: Connection refused则按以下顺序排查systemctl status tomcat看是否active若inactivejournalctl -u tomcat -n 50查错误若active但端口无监听ps aux | grep java看Java进程是否存在若进程存在netstat -tulnp | grep :8080确认端口绑定若端口绑定但curl不通检查/opt/tomcat/conf/server.xml中Connector的address属性是否为127.0.0.1默认是0.0.0.0若改过需恢复。4.2 国产Linux特殊处理统信UOS与麒麟V10统信UOS v20实操差异apt源默认无java-1.8.0-openjdk-devel需手动添加Oracle JDKsystemd版本为241Typeforking完全兼容最大坑/etc/default/locale中LANG默认为zh_CN.UTF-8但Tomcat8的catalina.sh在locale检测时会因LC_ALL未设而触发java.util.MissingResourceException。解决方案在/etc/default/tomcat中追加LANGen_US.UTF-8 LC_ALLen_US.UTF-8验证命令locale -a | grep en_US确认语言包存在不存在则sudo apt install language-pack-en-base。麒麟V10Kylin V10实操差异部分版本init为sysvinitsystemctl不可用。先确认ps -p 1 -o comm # 输出init或systemd若为init则创建/etc/init.d/tomcat#!/bin/bash # chkconfig: 2345 99 01 # description: Apache Tomcat init script # processname: tomcat CATALINA_HOME/opt/tomcat case $1 in start) sudo -u tomcat $CATALINA_HOME/bin/startup.sh /dev/null 21 ;; stop) sudo -u tomcat $CATALINA_HOME/bin/shutdown.sh /dev/null 21 ;; restart) $0 stop sleep 5 $0 start ;; *) echo Usage: $0 {start|stop|restart} exit 1 esac exit 0然后chmod x /etc/init.d/tomcat chkconfig --add tomcat chkconfig tomcat on service tomcat startchkconfig命令需yum install sysvinit-tools麒麟V10默认不装。4.3 启动失败典型日志分析与修复错误1Address already in use日志片段Caused by: java.net.BindException: Address already in use at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:433) at sun.nio.ch.Net.bind(Net.java:425) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)原因8080端口被占用。修复# 查找占用进程 ss -tlnp | grep :8080 # 或 lsof -i :8080 # 杀掉进程谨慎 kill -9 PID # 或改Tomcat端口编辑conf/server.xml改Connector port8080为port8081错误2Cannot find /opt/tomcat/bin/setenv.sh日志片段Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environment variable is needed to run this program原因setenv.sh不存在或无执行权。修复ls -l /opt/tomcat/bin/setenv.sh # 检查是否存在及权限 # 若无则重建若权限不对chmod x /opt/tomcat/bin/setenv.sh错误3SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8080]]日志片段org.apache.catalina.LifecycleException: Protocol handler start failed at org.apache.catalina.connector.Connector.startInternal(Connector.java:1039) ... Caused by: java.lang.UnsatisfiedLinkError: /usr/lib/jni/libtcnative-1.so: libapr-1.so.0: cannot open shared object file: No such file or directory原因tomcat-native库缺失依赖libapr。修复# CentOS yum install -y apr-devel openssl-devel # Ubuntu apt install -y libapr1-dev libssl-dev # 重新编译tomcat-native若已装或卸载 rm -f /opt/tomcat/lib/libtcnative-1.so注意国产系统若提示libapr-1.so.0找不到用find /usr -name libapr-1.so*定位创建软链ln -sf /usr/lib/x86_64-linux-gnu/libapr-1.so.0 /usr/lib/libapr-1.so.0。5. 常见问题与排查技巧实录5.1 启动服务报错速查表现象日志关键词根本原因修复命令systemctl status tomcat显示failedFailed at step EXEC spawningstartup.sh无执行权限chmod x /opt/tomcat/bin/startup.shcurl http://localhost:8080返回Connection refusedAddress already in use8080端口被占用ss -tlnp | grep :8080; kill -9 PIDjournalctl -u tomcat无输出No journal files were found.systemd未捕获日志检查/etc/systemd/system/tomcat.service中StandardOutputjournal是否生效重启服务