先说几个核心判断:在Linux系统上部署Java应用程序,虽然看似是一个老生常谈的话题,但真正能把每个环节都做到位、不出疏漏的团队其实并不多。从环境搭建到JVM参数调优,每一步都暗藏玄机,踩坑案例比比皆是。今天,我们就将整个部署流程拆解开来,逐一梳理清楚。
一、部署前准备

准备工作做扎实了,后续才能少走弯路。首先需要确认三件事:当前操作系统的具体版本是什么、Java运行环境是否已正确安装、系统资源是否充足。查看系统版本可使用 lsb_release -a 和 uname -a;检查Java环境则用 java -version 配合 echo $JAVA_HOME;内存信息用 free -h,CPU信息用 lscpu,磁盘空间用 df -h,网络连通性则通过 ping -c 4 google.com 来验证。
安全方面同样不能马虎。防火墙必须启用,同时要确保SSH(22端口)、HTTP(80端口)、HTTPS(443端口)以及应用端口(比如8080)都已放行。以Ubuntu的 ufw 为例,执行 sudo ufw enable && sudo ufw allow 22 && sudo ufw allow 8080 即可。此外,建议创建一个专用用户来运行应用,例如 sudo adduser appuser,再将其加入 sudo 组:sudo usermod -aG sudo appuser。SSH密钥认证也推荐配置好,将公钥写入 ~/.ssh/authorized_keys 即可。
再就是目录结构。一个清晰规范的标准目录能显著减少运维困扰。例如,将应用文件放在 /opt/myapp/{bin,conf,lib,logs,temp},日志文件单独放在 /var/log/myapp,配置文件放在 /etc/myapp。最后别忘了设置目录所属用户:sudo chown -R appuser:appuser /opt/myapp。
二、Java环境安装
安装Java环境,使用包管理器是最省心高效的方式。Debian/Ubuntu系列执行 sudo apt update && sudo apt install openjdk-11-jdk -y,将11替换为你需要的版本号即可。RHEL/CentOS系列则执行 sudo yum install java-11-openjdk-devel -y。安装完成后运行 java -version,看到版本信息即表示成功。
如果因特殊原因需要手动安装,步骤也不复杂。从Oracle官网下载JDK压缩包,例如 jdk-11.0.20_linux-x64_bin.tar.gz,上传至 /usr/local 并解压:sudo tar -zxvf jdk-11.0.20_linux-x64_bin.tar.gz -C /usr/local。然后编辑 /etc/profile,添加 export JAVA_HOME=/usr/local/jdk-11.0.20 和 export PATH=$JAVA_HOME/bin:$PATH,最后执行 source /etc/profile 使配置生效。
三、应用打包
无论使用Maven还是Gradle,打包这一步都是标准操作。Maven项目在根目录执行 mvn clean package,生成的JAR包会出现在 target 目录下。Gradle项目则执行 gradle build,JAR包位于 build/libs 中。如果是Web应用,需要部署到Tomcat这类Servlet容器,则要打成WAR包——Maven的 mvn package 同样会在 target 目录下生成WAR文件。
四、手动部署流程
部署方式取决于应用类型。WAR包走Tomcat部署时,先停止Tomcat服务:sudo systemctl stop tomcat。然后备份旧的WAR包:sudo cp /opt/tomcat/webapps/myapp.war /opt/tomcat/webapps/myapp.war.bak。将新包上传到 /tmp,再移动到 webapps 目录:sudo mv /tmp/myapp.war /opt/tomcat/webapps/。最后启动Tomcat:sudo systemctl start tomcat,并用 sudo tail -f /opt/tomcat/logs/catalina.out 监控日志查看部署状态。
JAR包部署(以Spring Boot为例)则更为直接。将JAR包上传到 /opt/myapp:scp myapp.jar appuser@server:/tmp && sudo mv /tmp/myapp.jar /opt/myapp/。如果应用已注册为systemd服务,先停止:sudo systemctl stop myapp,再启动:sudo systemctl start myapp,最后用 sudo systemctl status myapp 检查运行状态。
五、配置文件管理
配置文件和代码分离是基本素养。应用配置文件建议放在 /etc/myapp 下,例如 application.properties、application-prod.properties。数据库配置更要单独拎出来,放在 /etc/myapp/database.properties 里,内容包含数据库URL、用户名、密码等敏感信息。示例:spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC。
六、启动脚本编写
编写几个启动脚本,能让日常运维更加顺手。启动脚本 /opt/myapp/bin/start.sh 的核心逻辑是:检查PID文件判断应用是否已在运行,若未运行则用 nohup 启动JAR包,并将PID写入文件。停止脚本 /opt/myapp/bin/stop.sh 则相反,从PID文件读取进程ID,执行 kill 并等待进程结束。重启脚本 /opt/myapp/bin/restart.sh 更简单,先调用停止脚本,等待5秒,再调用启动脚本。别忘了赋予执行权限:chmod +x /opt/myapp/bin/*.sh。
七、systemd服务配置(可选但推荐)
使用systemd管理Java应用,是生产环境中最推荐的做法。创建 /etc/systemd/system/myapp.service 文件,内容包含Unit、Service、Install三部分。Service段需要注意:指定用户和组、工作目录、启动命令(包括JVM参数和Spring profile),以及重启策略(Restart=on-failure 配合 RestartSec=5s)。配置完成后,依次执行 sudo systemctl daemon-reload、sudo systemctl enable myapp、sudo systemctl start myapp,再用 sudo systemctl status myapp 确认状态。查看日志可用 journalctl -u myapp -f。
八、防火墙配置
如果使用 firewalld(CentOS系),开放应用端口(比如8080)的命令是:sudo firewall-cmd --permanent --add-port=8080/tcp && sudo firewall-cmd --reload。如果是 ufw(Ubuntu系),一句 sudo ufw allow 8080 就够了。
九、优化与维护
应用上线只是开始,长期维护才是重头戏。JVM调优方面,-Xms 和 -Xmx 分别设置初始堆内存和最大堆内存,例如 -Xms512m -Xmx2g。垃圾回收器选择上,-XX:+UseG1GC 配合 -XX:MaxGCPauseMillis=200,适合大内存应用。监控方面,使用 top 和 htop 查看CPU/内存占用,tail -f /opt/myapp/app.log 实时查看日志。如果想要更专业,集成Prometheus+Grafana做可视化监控,体验会非常顺畅。最后,备份策略不能忘:定期备份应用代码(/opt/myapp)、配置文件(/etc/myapp)和数据库(例如使用 mysqldump),并存储到异地或云存储。
