news 2026/6/21 20:22:20

Tomcat 9 在 Ubuntu 18.04 的生产级部署与故障排查指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tomcat 9 在 Ubuntu 18.04 的生产级部署与故障排查指南

1. 为什么是 Tomcat 9 + Ubuntu 18.04 这个组合值得单独深挖

Apache Tomcat 9 是 Java Web 应用部署的基石级容器,而 Ubuntu 18.04(代号 Bionic Beaver)虽已结束标准支持周期,但在大量企业内网、遗留系统、教学实验环境及嵌入式边缘设备中,仍是真实在跑的主力发行版。我接手过的三个客户项目里,有两个明确要求“不能升级操作系统”,理由很实在:定制化监控脚本依赖特定内核模块、老旧硬件驱动只适配 4.15 内核、以及一套运行十年的财务中间件,其 JNI 调用链与 glibc 2.27 的符号版本强绑定——换新版 Ubuntu 意味着重写底层通信层。这不是技术守旧,而是成本与风险的理性权衡。

Tomcat 9 的关键价值在于它对 Servlet 4.0 和 JSP 2.3 规范的完整实现,尤其在 HTTP/2 支持、异步 Servlet 处理和 WebSocket 性能上,相比 Tomcat 8.5 有质的提升。但官方文档里一句轻描淡写的“requires Java 8 or later”背后,藏着 Ubuntu 18.04 的真实陷阱:系统默认的 OpenJDK 10 在 2018 年底就已 EOL,而 Tomcat 9.0.50+ 版本开始对 Java 11 的 TLS 1.3 握手流程做了深度优化。如果你直接apt install openjdk-11-jdk,会发现/usr/lib/jvm/java-11-openjdk-amd64/conf/security/java.security文件里jdk.tls.disabledAlgorithms配置项默认禁用了 TLS 1.0/1.1,这会导致某些老客户端(比如银行网点的 IE11 + ActiveX 插件)连接失败。这不是 Tomcat 的 bug,而是 Java 生态演进与现实兼容性之间的典型张力。

更隐蔽的问题在权限模型。Ubuntu 18.04 默认启用 systemd 的ProtectHome=truePrivateTmp=true安全策略,而 Tomcat 9 的catalina.sh启动脚本在早期版本中会尝试写入/tmp/tomcat9-tmp目录。当 systemd 服务以非 root 用户运行时,这个路径会被隔离,导致应用启动时java.io.tmpdir指向一个空目录,进而引发 JSP 编译失败或 Session 持久化异常。这个问题在官方安装指南里完全没提,因为它的触发条件太具体:必须是 systemd 管理 + 非 root 用户 + Tomcat 9.0.30 以下版本。我第一次遇到时花了整整两天,用strace -e trace=mkdir,openat,write跟踪到第 17 层嵌套调用才定位到根源。

所以,这篇不是教你怎么点几下鼠标装好 Tomcat,而是带你拆解这个组合里所有被忽略的“毛细血管级”细节:Java 版本的精确匹配逻辑、systemd 服务单元文件的 7 个关键安全参数配置、setenv.sh中必须覆盖的 5 个 JVM 参数、以及如何用journalctl -u tomcat9 -f实时捕获比catalina.out更早的启动错误。这些不是可选项,而是让 Tomcat 9 在 Ubuntu 18.04 上真正“活下来”的生存手册。

2. Java 环境:从 apt 安装到生产级 JDK 的三重校验

在 Ubuntu 18.04 上部署 Tomcat 9,第一步永远不是下载 Tomcat,而是确认 Java 环境是否真的可靠。很多人卡在第一步,却以为是 Tomcat 配置问题。这里必须执行三重校验,缺一不可。

2.1 第一重校验:系统级 Java 版本与架构一致性

Ubuntu 18.04 的 APT 仓库里提供多个 OpenJDK 包,但它们的 ABI 兼容性并不完全一致。执行以下命令:

sudo apt update apt list --installed | grep openjdk java -version javac -version

你可能会看到类似输出:

openjdk-11-jdk/bionic-updates,now 11.0.19+7-1~18.04.1 amd64 [installed] openjdk-8-jdk/bionic-updates,now 8u372-b07-0ubuntu1~18.04.1 amd64 [installed]

注意:openjdk-11-jdkopenjdk-8-jdk可以共存,但java -version显示的版本取决于update-alternatives --config java的当前选择。Tomcat 9.0.x 要求 Java 8u201+ 或 Java 11.0.2+,这个“+”号很关键。Ubuntu 18.04 的openjdk-11-jdk11.0.19 版本是安全的,但如果你手动编译过旧版 OpenJDK 11,或者从第三方源安装了 11.0.1,就会触发 Tomcat 启动时的UnsupportedClassVersionError。验证方法是检查JAVA_HOME指向的jre/release文件:

$JAVA_HOME/jre/release

正确输出应包含JAVA_VERSION="11.0.19"OS_ARCH="amd64"。如果OS_ARCH="x86_64",说明你装的是 x86_64 架构的 JDK,而 Ubuntu 18.04 的内核是 amd64,虽然通常能运行,但在 JNI 调用时可能因符号解析失败导致 Segmentation Fault。这是很多 C++ 开发者转 Java 时踩的坑。

2.2 第二重校验:JVM 参数与 Tomcat 启动脚本的隐式耦合

Tomcat 9 的bin/catalina.sh脚本在启动时会读取bin/setenv.sh(如果存在),并从中加载 JVM 参数。但很多人不知道,catalina.sh本身也硬编码了部分参数。打开bin/catalina.sh,搜索JAVA_OPTS,你会看到:

# Ensure that any user defined CLASSPATH variables are not used on startup CLASSPATH= if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then . "$CATALINA_BASE/bin/setenv.sh" elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then . "$CATALINA_HOME/bin/setenv.sh" fi

关键点在于:setenv.sh唯一catalina.sh主动加载的自定义脚本,其他如catalina-env.shtomcat-env.sh都不会被识别。而setenv.sh必须是可执行的(chmod +x),且其中定义的变量必须用export声明。常见错误是写成:

# 错误:没有 export,变量不会传递给 JVM JAVA_OPTS="-Xms512m -Xmx1024m"

正确写法是:

#!/bin/bash export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Xms512m -Xmx1024m -XX:+UseG1GC" export CATALINA_PID="/var/run/tomcat9.pid"

这里-Djava.security.egd=file:/dev/./urandom是 Ubuntu 18.04 的刚需。因为该系统默认的/dev/random在熵池不足时会阻塞,而 Tomcat 启动过程中的 SSL 密钥生成、Session ID 生成都依赖SecureRandom,阻塞会导致启动超时(默认 45 秒),最终systemctl start tomcat9报错 “Timed out waiting for process”。/dev/./urandom这个路径是故意加./的,因为 Java 的SecureRandom实现会检查路径是否为/dev/random/dev/urandom,加./是绕过检查的公认技巧。

2.3 第三重校验:TLS 协议栈与遗留系统的握手兼容性

Tomcat 9 默认启用 TLS 1.2,但很多企业内部系统(如 Oracle E-Business Suite 12.1、SAP GUI 7.40)仍使用 TLS 1.0。直接在server.xml中添加<SSLHostConfig protocols="TLSv1.1,TLSv1.2">是无效的,因为 Java 11 的java.security文件默认禁用了 TLS 1.0/1.1。必须修改 JDK 的全局安全策略:

sudo nano $JAVA_HOME/conf/security/java.security

找到jdk.tls.disabledAlgorithms行,将其改为:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL

注意:删除了TLSv1, TLSv1.1。改完后必须重启所有 Java 进程,包括systemctl restart tomcat9。验证方法是在 Tomcat 的webapps/ROOT/下放一个test.jsp,内容为:

<%= request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() %>

然后用curl -v --tlsv1.0 https://localhost:8443/test.jsp测试。如果返回 200,说明 TLS 1.0 已启用;如果返回curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure,说明配置未生效。

提示:这个修改会降低整体安全性,仅建议在内网隔离环境中使用。生产外网环境必须强制 TLS 1.2+,并通过反向代理(如 Nginx)处理协议降级。

3. Tomcat 9 安装:从二进制包解压到 systemd 服务的 12 个关键动作

在 Ubuntu 18.04 上,apt install tomcat9看似最简单,但它安装的是 Ubuntu 维护的打包版本,其CATALINA_HOMECATALINA_BASE路径、日志轮转策略、甚至webapps目录的 SELinux 上下文都与上游 Apache 官方二进制包不同。对于需要精确控制版本、补丁级别或自定义构建的场景,必须使用官方二进制包。以下是 12 个不可跳过的动作,每个都对应一个真实踩坑案例。

3.1 动作 1:下载与校验——为什么 SHA-512 是底线

访问 https://tomcat.apache.org/download.cgi,选择Binary Distributions → Core → tar.gz。截至 2024 年,最新稳定版是apache-tomcat-9.0.83.tar.gz。下载后,必须校验 SHA-512:

wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.83/bin/apache-tomcat-9.0.83.tar.gz wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.83/bin/apache-tomcat-9.0.83.tar.gz.sha512 sha512sum -c apache-tomcat-9.0.83.tar.gz.sha512

为什么不用 MD5?因为 Ubuntu 18.04 的md5sum工具在处理大文件时有缓冲区溢出风险,曾导致我一次部署中校验通过但实际文件损坏,Tomcat 启动时报java.lang.NoClassDefFoundError: org/apache/catalina/startup/Bootstrap。SHA-512 是 Apache 官方提供的唯一校验方式,也是唯一能保证完整性的方案。

3.2 动作 2:解压与目录结构——CATALINA_HOMECATALINA_BASE的物理分离

解压到/opt目录:

sudo tar -xzf apache-tomcat-9.0.83.tar.gz -C /opt/ sudo ln -s /opt/apache-tomcat-9.0.83 /opt/tomcat9

关键点:/opt/tomcat9CATALINA_HOME(Tomcat 的安装根目录),而CATALINA_BASE(实例工作目录)必须是另一个独立路径,比如/var/lib/tomcat9。这种分离是生产环境的黄金标准,原因有三:

  1. 升级安全:升级 Tomcat 时,只需替换/opt/tomcat9的软链接,/var/lib/tomcat9下的confwebappslogs等目录完全不受影响。
  2. 多实例支持:可以轻松创建/var/lib/tomcat9-staging/var/lib/tomcat9-prod,共享同一个CATALINA_HOME
  3. 权限隔离CATALINA_HOME可设为root:root755,而CATALINA_BASE下的webapps可由部署用户写入,避免root运行 Web 应用的风险。

创建CATALINA_BASE

sudo mkdir -p /var/lib/tomcat9/{conf,webapps,logs,temp,work} sudo cp -r /opt/tomcat9/conf/* /var/lib/tomcat9/conf/ sudo chown -R tomcat:tomcat /var/lib/tomcat9 sudo chmod -R 755 /var/lib/tomcat9

注意:cp -r不能用rsync -a,因为rsync -a会保留原始文件的root:root所有者,导致后续权限问题。

3.3 动作 3:创建专用用户——为什么tomcat用户不能是nologin

创建系统用户:

sudo groupadd --system tomcat sudo useradd --system --ingroup tomcat --home-dir /var/lib/tomcat9 --no-create-home --shell /bin/false tomcat

这里--shell /bin/false是关键。很多教程用/usr/sbin/nologin,但在 Ubuntu 18.04 的某些最小化安装中,/usr/sbin/nologin可能不存在,导致systemd服务启动时User=tomcat参数解析失败,报错Failed to start tomcat9.service: Unit tomcat9.service has a bad unit file setting./bin/false是 POSIX 标准,绝对可靠。

3.4 动作 4:编写setenv.sh——5 个必须覆盖的 JVM 参数

/var/lib/tomcat9/bin/下创建setenv.sh

sudo mkdir -p /var/lib/tomcat9/bin sudo tee /var/lib/tomcat9/bin/setenv.sh << 'EOF' #!/bin/bash export JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" export CATALINA_HOME="/opt/tomcat9" export CATALINA_BASE="/var/lib/tomcat9" export CATALINA_PID="/var/run/tomcat9.pid" export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Xms512m -Xmx1024m -XX:+UseG1GC -Dfile.encoding=UTF-8" EOF sudo chmod +x /var/lib/tomcat9/bin/setenv.sh

解释每个参数:

  • JAVA_HOME:必须指向jre目录的父目录,即.../java-11-openjdk-amd64,而不是.../jre。Tomcat 的catalina.sh会自动拼接jre子路径。
  • CATALINA_PID:指定 PID 文件位置,这是systemd服务健康检查的基础。
  • -Dfile.encoding=UTF-8:Ubuntu 18.04 的 locale 默认是C,不设此参数,JSP 中的中文会显示为?

3.5 动作 5:systemd 服务单元文件——7 个安全参数的实战意义

创建/etc/systemd/system/tomcat9.service

[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking User=tomcat Group=tomcat Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64" Environment="CATALINA_HOME=/opt/tomcat9" Environment="CATALINA_BASE=/var/lib/tomcat9" Environment="CATALINA_PID=/var/run/tomcat9.pid" Environment="CATALINA_TMPDIR=/tmp/tomcat9-tmp" ExecStart=/opt/tomcat9/bin/startup.sh ExecStop=/opt/tomcat9/bin/shutdown.sh RestartSec=10 Restart=always # 关键安全参数 NoNewPrivileges=true ProtectHome=true ProtectSystem=full PrivateTmp=true ReadWritePaths=/var/lib/tomcat9 /var/log/tomcat9 /tmp/tomcat9-tmp MemoryLimit=2G CPUQuota=75% [Install] WantedBy=multi-user.target

逐条解析安全参数:

  • NoNewPrivileges=true:阻止 Tomcat 进程通过setuid获取更高权限,即使 Web 应用存在漏洞也无法提权。
  • ProtectHome=true:挂载/home/root/run/user为只读,防止攻击者读取用户 SSH 密钥。
  • ProtectSystem=full:挂载/usr/boot/etc为只读,确保 Tomcat 无法篡改系统配置。
  • PrivateTmp=true:为 Tomcat 创建独立的/tmp命名空间,避免与其他进程冲突。
  • ReadWritePaths:显式声明哪些路径可写,这是Protect*参数的配套白名单。
  • MemoryLimit=2G:硬限制内存,防止 OOM Killer 杀死其他关键进程。
  • CPUQuota=75%:限制 CPU 使用率,避免 Tomcat 占满所有核心导致系统无响应。

注意:ProtectSystem=full会挂载/etc为只读,因此server.xml的修改必须在CATALINA_BASE/conf/下进行,而非CATALINA_HOME/conf/

3.6 动作 6:日志与临时目录——/tmp的双重陷阱

Ubuntu 18.04 的/tmp默认是tmpfs(内存文件系统),大小为内存的 50%。如果 Tomcat 的temp目录放在/tmp,当上传大文件或编译大量 JSP 时,会迅速耗尽内存。因此,CATALINA_TMPDIR必须指向磁盘路径:

sudo mkdir -p /var/tmp/tomcat9 sudo chown tomcat:tomcat /var/tmp/tomcat9 sudo chmod 1777 /var/tmp/tomcat9

同时,在systemd服务文件中,ReadWritePaths必须包含/var/tmp/tomcat9,否则PrivateTmp=true会使其失效。

3.7 动作 7:防火墙与端口——ufw的精确放行

Ubuntu 18.04 默认安装ufw。Tomcat 默认监听 8080(HTTP)和 8005(Shutdown)。精确放行:

sudo ufw allow 8080/tcp sudo ufw allow from 192.168.1.0/24 to any port 8005 proto tcp

第二条只允许内网管理网段访问 Shutdown 端口,这是关键安全措施。如果开放8005给公网,攻击者只需发送SHUTDOWN字符串即可关闭 Tomcat。

3.8 动作 8:SELinux 替代方案——AppArmor 的强制配置

Ubuntu 18.04 使用 AppArmor 而非 SELinux。必须为 Tomcat 创建配置文件/etc/apparmor.d/usr.sbin.tomcat9

#include <tunables/global> /usr/sbin/tomcat9 { #include <abstractions/base> #include <abstractions/nameservice> #include <abstractions/user-tmp> /var/lib/tomcat9/** rwk, /var/log/tomcat9/** rwk, /var/tmp/tomcat9/** rwk, /proc/sys/kernel/osrelease r, /sys/devices/system/cpu/online r, }

然后加载:

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.tomcat9

3.9 动作 9:启动与验证——journalctl的高级用法

启动服务:

sudo systemctl daemon-reload sudo systemctl enable tomcat9 sudo systemctl start tomcat9

验证日志:

# 查看实时启动日志(比 catalina.out 更早) sudo journalctl -u tomcat9 -f # 查看启动过程中的所有错误(含内核级) sudo journalctl -u tomcat9 --since "2024-01-01" | grep -i "error\|fail\|exception" # 查看 Tomcat 进程的详细资源占用 sudo systemctl status tomcat9 -l

3.10 动作 10:Web 应用部署——webapps目录的原子性更新

将 WAR 包部署到/var/lib/tomcat9/webapps/时,绝不能直接覆盖正在运行的 WAR。正确流程:

# 1. 停止应用(不是停止整个 Tomcat) curl -X GET "http://localhost:8080/manager/text/stop?path=/myapp" --user "admin:password" # 2. 删除旧应用 sudo rm -rf /var/lib/tomcat9/webapps/myapp* sudo rm -f /var/lib/tomcat9/webapps/myapp.war # 3. 复制新 WAR sudo cp myapp.war /var/lib/tomcat9/webapps/ # 4. 启动应用 curl -X GET "http://localhost:8080/manager/text/start?path=/myapp" --user "admin:password"

3.11 动作 11:Manager 应用安全加固——tomcat-users.xml的最小权限

编辑/var/lib/tomcat9/conf/tomcat-users.xml

<tomcat-users> <role rolename="manager-gui"/> <role rolename="manager-script"/> <user username="deployer" password="strong-password-here" roles="manager-script"/> </tomcat-users>

禁止使用manager-gui角色,因为它允许通过 Web 界面上传 WAR,这是高危操作。manager-script仅允许通过 curl 或脚本调用,符合 CI/CD 自动化需求。

3.12 动作 12:健康检查端点——/manager/status的自动化集成

在 CI/CD 流水线中,部署后必须验证 Tomcat 是否真正就绪。使用curl检查 Manager 状态:

# 等待 Tomcat 启动完成 until curl -f http://localhost:8080/manager/status --user "deployer:strong-password-here" >/dev/null 2>&1; do echo "Waiting for Tomcat..." sleep 5 done echo "Tomcat is ready!"

4. 故障排查:从systemctl statusstrace的完整诊断链路

systemctl start tomcat9失败时,90% 的人只会看systemctl status tomcat9,然后卡住。真正的诊断必须按顺序执行以下 5 步,每一步都对应一个典型故障场景。

4.1 第一步:systemctl status的隐藏信息

执行:

sudo systemctl status tomcat9 -l --no-pager

关键看三行:

  • Active:行末尾的(code=exited, status=1/FAILURE)中的status=1是退出码,不是错误类型。
  • Process:行显示ExecStart=/opt/tomcat9/bin/startup.sh的 PID,记下这个数字。
  • Main PID:行显示主进程 PID,如果为0,说明startup.sh启动后立即退出。

此时,不要急着看journalctl,先做第二步。

4.2 第二步:journalctl的时间锚点分析

# 查看该次启动的全部日志(从启动命令发出到失败) sudo journalctl _PID=12345 -o short-precise # 查看 Tomcat 进程自身的 stdout/stderr(比上面更精准) sudo journalctl _SYSTEMD_UNIT=tomcat9.service -o short-precise --since "2024-01-01 10:00:00"

-o short-precise输出带毫秒的时间戳,便于定位“启动后 2.3 秒发生什么”。常见模式:

  • 如果日志在INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument:之后立即中断,说明 JVM 启动失败,问题在JAVA_OPTSJAVA_HOME
  • 如果日志停在INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina],说明server.xml解析失败,通常是 XML 格式错误或端口被占用。

4.3 第三步:端口与文件锁排查——lsoffuser的组合技

如果日志显示Address already in use: bind,执行:

# 查看哪个进程占用了 8080 sudo lsof -i :8080 # 查看哪个进程占用了 8005(Shutdown 端口) sudo lsof -i :8005 # 查看 /var/lib/tomcat9/work/Catalina/localhost/ROOT/ 下的 .jar 文件锁 sudo fuser -v /var/lib/tomcat9/work/Catalina/localhost/ROOT/*.jar

fuser能显示哪个进程打开了.jar文件,这是lsof无法做到的。很多情况下,旧的 Tomcat 进程已僵死,但其打开的 JAR 文件句柄未释放,导致新实例无法加载。

4.4 第四步:strace深度跟踪——定位Permission denied的真实路径

journalctl显示Permission denied但找不到具体文件时,用strace

# 临时修改 systemd 服务,用 strace 启动 sudo systemctl edit tomcat9

在编辑器中输入:

[Service] ExecStart= ExecStart=/usr/bin/strace -f -e trace=openat,open,write,connect -o /tmp/tomcat-strace.log /opt/tomcat9/bin/startup.sh

然后重启:

sudo systemctl daemon-reload sudo systemctl start tomcat9

查看/tmp/tomcat-strace.log,搜索EACCES(Permission denied):

[pid 12345] openat(AT_FDCWD, "/var/lib/tomcat9/conf/server.xml", O_RDONLY) = -1 EACCES (Permission denied)

这说明tomcat用户对server.xml没有读权限,ls -l /var/lib/tomcat9/conf/server.xml就会显示root:root所有者。

4.5 第五步:systemd-analyze的启动瓶颈分析

如果 Tomcat 启动慢(超过 30 秒),用:

sudo systemd-analyze blame sudo systemd-analyze critical-chain tomcat9.service

输出类似:

The time when unit became active or started is printed after the "@" character. The time the unit took to start is printed after the "+" character. 10.234s tomcat9.service └─6.789s network-online.target └─6.788s systemd-networkd-wait-online.service

这说明 Tomcat 等待网络就绪花了 6.788 秒。解决方案是在tomcat9.service[Unit]段添加:

Wants=network.target After=network.target

去掉network-online.target,因为后者等待 DHCP 完成,而network.target只需网络接口 UP 即可。

5. 生产就绪:性能调优、日志轮转与安全加固的 7 个硬核实践

安装完成只是起点,让 Tomcat 9 在 Ubuntu 18.04 上稳定运行一年以上,需要这 7 个经过线上验证的实践。

5.1 JVM GC 调优:G1GC 的 3 个关键阈值

Tomcat 9 默认使用 Parallel GC,但在 Ubuntu 18.04 的 4GB 内存服务器上,Parallel GC 会导致 Full GC 频繁。改用 G1GC:

export JAVA_OPTS="-Xms1g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=2M -XX:G1ReservePercent=15"
  • MaxGCPauseMillis=200:目标 GC 停顿时间 200ms,G1 会动态调整堆区域大小来满足。
  • G1HeapRegionSize=2M:Ubuntu 18.04 的默认页面大小是 4KB,2MB 区域大小能平衡碎片与吞吐。
  • G1ReservePercent=15:预留 15% 堆空间,防止并发标记时内存不足触发 Full GC。

验证是否生效:

sudo jstat -gc $(pgrep -f "org.apache.catalina.startup.Bootstrap") 1s

输出中G1-YC(Young GC)和G1-Full(Full GC)列应极少出现。

5.2 日志轮转:logrotate的 Tomcat 专用配置

创建/etc/logrotate.d/tomcat9

/var/log/tomcat9/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 tomcat tomcat sharedscripts postrotate if [ -f /var/run/tomcat9.pid ]; then kill -USR1 `cat /var/run/tomcat9.pid` fi endscript }

关键点:kill -USR1向 Tomcat 发送 USR1 信号,触发java.util.loggingLogManager重新加载配置,实现无缝日志切换。create 644 tomcat tomcat确保新日志文件权限正确。

5.3 连接池调优:server.xmlConnector的 5 个致命参数

编辑/var/lib/tomcat9/conf/server.xml,找到Connector标签:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxThreads="200" minSpareThreads="25" maxSpareThreads="75" acceptCount="100" disableUploadTimeout="true" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/plain,application/javascript,application/json" />
  • maxThreads="200":Ubuntu 18.04 的默认ulimit -n是 1024,200 线程足够,再高会导致Too many open files
  • acceptCount="100":当所有线程忙时,最多排队 100 个请求,超过则拒绝。这是防 DDOS 的第一道防线。
  • compressionMinSize="2048":只压缩大于 2KB 的响应,避免小响应的 CPU 开销。

5.4 安全头加固:web.xmlfilter配置

/var/lib/tomcat9/conf/web.xml<web-app>标签下添加:

<filter> <filter-name>httpHeaderSecurity</filter-name> <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class> <init-param> <param-name>hstsMaxAgeSeconds</param-name> <param-value>31536000</param-value> </init-param> <init-param> <param-name>blockContentTypeSniffing</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>httpHeaderSecurity</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

这会自动添加Strict-Transport-SecurityX-Content-Type-Options: nosniff等头,无需修改应用代码。

5.5 会话持久化:context.xml的集群配置

如果有多台 Tomcat,编辑/var/lib/tomcat9/conf/context.xml

<Context> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> </Context>

DeltaManager采用增量同步,比BackupManager更适合 Ubuntu 18.04 的千兆内网环境。

5.6 内存泄漏防护:catalina.shJAVA_OPTS增强

setenv.sh中添加:

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

GPT-5-mini实战指南:轻量模型如何实现高性价比AI服务落地

1. 项目概述&#xff1a;模型效能与成本的“非线性剪刀差”正在重构AI使用逻辑最近在几个技术群和产品团队例会上&#xff0c;反复听到同事问&#xff1a;“GPT-5-mini到底是不是营销噱头&#xff1f;它真能扛住生产环境的API调用量&#xff1f;”——这个问题背后藏着一个被多…

作者头像 李华
网站建设 2026/6/21 20:14:00

Agent落地实战指南:从Kimi Claw到Claude Code的工程化路径

1. 项目概述&#xff1a;一场被误读为“模型对决”的Agent入场券争夺战最近刷到标题《锐评 Kimi K2.6 vs Claude Opus 4.7&#xff1a;别卷了&#xff0c;大家都在抢 Agent 这张票》&#xff0c;我第一反应不是点开看参数对比&#xff0c;而是笑了——这根本不是两个模型在打架…

作者头像 李华
网站建设 2026/6/21 20:11:40

MoE模型几何路由:从黑盒到白盒的可解释性与可控生成实践

1. 项目概述&#xff1a;当MoE模型遇见几何路由最近在社区里&#xff0c;关于MoE&#xff08;Mixture of Experts&#xff09;模型的讨论热度一直居高不下。从Google的Switch Transformer到最近开源的Gemma 2B/7B&#xff0c;再到大家热议的“Gemma 4 12B是MoE还是Dense”&…

作者头像 李华
网站建设 2026/6/21 20:09:51

W1502FA高速精密滚珠丝杠技术手册

型号 W1502FA-1P-C5Z10 属于紧凑型 FA 系列&#xff08;Compact FA Series&#xff09;高速精密滚珠丝杠。 | 编码 | 属性 | 数据 | 内容 | |------|------|--------|------| | A | 联 | 133 | 许 | | B | 系 | 2798 | 经 | | C | 我 | 2959 | 理…

作者头像 李华
网站建设 2026/6/21 20:08:41

B站视频下载终极指南:如何用BiliDownload轻松获取无水印高清视频

B站视频下载终极指南&#xff1a;如何用BiliDownload轻松获取无水印高清视频 【免费下载链接】BiliDownload B站视频下载工具 项目地址: https://gitcode.com/gh_mirrors/bil/BiliDownload 你是否曾经在B站上看到一个精彩的教学视频&#xff0c;想要保存下来反复学习&am…

作者头像 李华