Skip to content

J2EE 应用 Linux 部署标准流程 ​

本文适用于基于 Servlet/JSP 的传统 J2EE Web 应用(如使用 Apache Tomcat 作为容器),目标是构建可复现、可维护、符合最小权限原则的生产级部署方案。不适用于 Spring Boot 内嵌容器模式(其部署范式不同,详见《Spring Boot 应用 Linux 部署指南》)。

🎯 目标 ​

  • 将编译打包完成的 .war 文件安全、可靠地部署至 Linux 服务器;
  • 启动受 systemd 管理的 Tomcat 服务,支持开机自启与日志归集;
  • 避免常见权限、编码、路径配置错误导致的启动失败或运行时异常;
  • 满足基础安全要求:非 root 运行、独立用户隔离、静态资源权限收敛。

⚙️ 前置条件 ​

系统环境 ​

  • 操作系统:CentOS 7+/Rocky Linux 8+ 或 Ubuntu 20.04+(推荐 LTS 版本);
  • 内存:≥2 GB(建议 4 GB+,视应用规模调整);
  • Java 运行时:OpenJDK 11 或 17(必须与应用编译版本兼容);
    bash
    java -version  # 输出应类似:openjdk version "17.0.1"...

必备组件 ​

  • Apache Tomcat 9.x 或 10.x(注意:Tomcat 10+ 默认启用 Jakarta EE 9+ 命名空间,需确认应用已迁移 jakarta.* 包);
  • systemd(现代 Linux 发行版默认启用);
  • unzip、curl、rsync(用于传输与解压)。

权限与用户约定 ​

  • 禁止以 root 用户直接运行 Tomcat;
  • 创建专用低权限用户(如 tomcat),归属独立用户组(如 tomcat);
  • 所有 Tomcat 目录(CATALINA_HOME、CATALINA_BASE)归属该用户,权限设为 750;
  • WAR 包上传目录(如 /opt/deploy/)对部署用户可写,对 tomcat 用户只读。

🛠️ 标准部署步骤 ​

1. 创建部署用户与目录结构 ​

bash
# 创建用户(无登录 shell,主目录禁用)
sudo useradd -r -s /bin/false -d /opt/tomcat tomcat

# 创建标准目录结构
sudo mkdir -p /opt/tomcat/{bin,conf,logs,webapps,work,temp}
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod -R 750 /opt/tomcat

# 创建部署中转目录(供 CI/CD 或人工上传)
sudo mkdir -p /opt/deploy
sudo chown deployer:deployer /opt/deploy  # 假设由 deployer 用户上传
sudo chmod 755 /opt/deploy

2. 配置 Tomcat 运行环境 ​

编辑 /opt/tomcat/bin/setenv.sh(若不存在则新建),设置关键 JVM 参数与编码:

bash
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64  # 根据实际路径调整
export CATALINA_HOME=/opt/tomcat
export CATALINA_BASE=/opt/tomcat
export CATALINA_PID=/opt/tomcat/tomcat.pid
export CATALINA_OUT=/opt/tomcat/logs/catalina.out

# 关键:强制 UTF-8 编码(避免中文乱码、表单提交异常)
export JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"

# 生产建议:堆内存与 GC 策略
export JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200"

✅ 注意:setenv.sh 需添加执行权限:sudo chmod +x /opt/tomcat/bin/setenv.sh

3. 部署 WAR 包 ​

bash
# 假设 WAR 包已上传至 /opt/deploy/myapp.war
sudo cp /opt/deploy/myapp.war /opt/tomcat/webapps/

# Tomcat 会自动解压(确保 webapps 目录下无同名目录残留)
# 如需跳过自动解压,可重命名为 myapp.war?unpack=false(Tomcat 9+)

# 推荐方式:先清空再部署(避免旧 class/配置残留)
sudo systemctl stop tomcat
sudo rm -rf /opt/tomcat/webapps/myapp*  # 清理历史版本
sudo cp /opt/deploy/myapp.war /opt/tomcat/webapps/
sudo chown tomcat:tomcat /opt/tomcat/webapps/myapp.war

4. 编写 systemd 服务单元文件 ​

创建 /etc/systemd/system/tomcat.service:

ini
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking
User=tomcat
Group=tomcat
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx2G -server -XX:+UseG1GC'
Environment='JAVA_OPTS=-Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

启用并启动服务:

bash
sudo systemctl daemon-reload
sudo systemctl enable tomcat
sudo systemctl start tomcat
sudo systemctl status tomcat  # 验证运行状态

5. 验证与基础访问控制 ​

  • 检查端口监听:sudo ss -tuln | grep :8080;
  • 访问 http://<server-ip>:8080/myapp/(确保应用上下文路径正确);
  • 查看日志定位问题:sudo journalctl -u tomcat -f 或 tail -f /opt/tomcat/logs/catalina.out;
  • 关闭 Tomcat Manager 默认页面(生产必需):
    • 删除 /opt/tomcat/webapps/manager 和 /opt/tomcat/webapps/host-manager;
    • 或注释 /opt/tomcat/conf/tomcat-users.xml 中相关 <role> 与 <user> 配置。

⚠️ 关键注意事项 ​

  • WAR 包命名即上下文路径:myapp.war → 访问路径为 /myapp/;ROOT.war → 访问根路径 /;
  • 时区一致性:确保服务器 TZ 与应用 JVM 时区一致(推荐 export JAVA_OPTS="$JAVA_OPTS -Duser.timezone=Asia/Shanghai");
  • 静态资源缓存:如使用 Nginx 做反向代理,务必配置 Cache-Control 头,避免浏览器加载过期 JS/CSS;
  • JDBC 连接池配置:生产环境应将数据库连接信息移出 WEB-INF/web.xml,改用 JNDI 或外部配置(如 context.xml),避免敏感信息硬编码;
  • SELinux / AppArmor:如启用,需额外放行 Tomcat 网络端口与文件访问策略(CentOS/RHEL 默认启用 SELinux)。

❓ 常见问题排查 ​

现象可能原因解决方案
Failed to start tomcat.service: Unit tomcat.service not foundsystemd 单元文件路径错误或未重载检查文件路径是否为 /etc/systemd/system/tomcat.service;执行 sudo systemctl daemon-reload
启动后 8080 端口无响应,日志无报错Tomcat 进程崩溃退出(PID 文件残留)清理 /opt/tomcat/tomcat.pid,重启服务;检查 JAVA_HOME 路径是否真实存在
中文参数乱码(如表单提交)请求编码未统一在 conf/server.xml 的 Connector 中添加 URIEncoding="UTF-8":
<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" ... />
java.lang.OutOfMemoryError: MetaspaceMetaspace 不足(尤其热部署频繁时)在 setenv.sh 中添加:
export JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
WAR 包未自动解压autoDeploy="false" 或 deployOnStartup="false"检查 conf/server.xml 中 <Host> 标签属性,确保为默认值 true

如何把J2EE应用部署到LINUX https://how2j.cn/k/deploy2linux/deploy2linux-breif/1591.html#nowhere ​

方舟 · Ark