
1.前期准备环境依赖检查1.1 JDK版本与安装坑开发环境使用JDK 11服务器仅安装JRE 8导致类版本错误UnsupportedClassVersionError。正确做法确保服务器JDK版本 ≥ 开发版本且位数一致64位。推荐使用相同的JDK发行版如OpenJDK、Oracle JDK避免细微差异。通过 java -version 验证并配置 JAVA_HOME 环境变量。1.2 环境变量与PATH坑使用 java -jar 时提示“command not found”因 java 未加入PATH。正确做法编辑 /etc/profile 或用户 ~/.bashrc添加export JAVA_HOME/usr/lib/jvm/java-11-openjdk export PATH$JAVA_HOME/bin:$PATH执行 source 生效后测试。1.3 外部依赖服务坑应用启动时报数据库连接失败、Redis无法访问原因是目标服务未启动或网络不通。正确做法提前准备好数据库、缓存、消息队列等中间件并验证连通性如 telnet ip port。确保防火墙iptables/firewalld或安全组策略已开放所需端口。2. 打包与构建2.1 打包为可执行JAR坑打包时未包含依赖导致服务器上运行时类缺失ClassNotFoundException。正确做法使用Spring Boot Maven插件spring-boot-maven-plugin或Gradle构建“fat JAR”。检查 pom.xml 中插件配置确保 repackage 目标执行。验证JAR包大小通常几MB到几十MB若过小可能缺少依赖。2.2 配置文件外置坑将不同环境的配置dev/prod打包进JAR导致部署时需要重新打包或修改源码。正确做法遵循“配置与代码分离”原则使用 application.yml 外部化。启动时通过 --spring.config.location 指定外部配置文件java -jar app.jar --spring.config.location/opt/app/config/application-prod.yml或利用Spring Boot的优先级机制在JAR同目录下放置 application.yml 或 config/application.yml。3. 上传与权限管理3.1 文件传输坑使用 rz/sz 传输大文件导致中断或损坏或通过FTP明文传输存在安全风险。正确做法推荐使用 scp 或 rsync支持断点续传scp app.jar userserver:/opt/app/rsync -avzP app.jar userserver:/opt/app/若需频繁部署可考虑CI/CD工具Jenkins、GitLab CI自动拉取。3.2 文件权限与用户坑使用root用户直接运行应用一旦被入侵将获得最高权限或文件权限过松如777。正确做法创建专用系统用户如 appuser运行应用并赋予JAR文件644权限、启动脚本755权限。useradd -m -s /bin/bash appuserchown -R appuser:appuser /opt/appchmod 755 /opt/app/*.shchmod 644 /opt/app/*.jar4. 启动脚本与进程管理4.1 编写健壮的启动脚本坑直接使用 java -jar 启动退出SSH后进程终止或没有停止脚本导致重复启动。正确做法使用 nohup 或 systemd 管理进程。示例启动脚本 start.sh#!/bin/bashAPP_NAMEapp.jarLOG_DIR/var/log/myappPID_FILE/var/run/myapp.pid# 创建日志目录mkdir-p$LOG_DIR# 检查是否已运行if[-f$PID_FILE]kill-0$(cat$PID_FILE)2/dev/null;thenechoApplication already running.exit1fi# 启动应用nohupjava-jar$APP_NAME\--spring.profiles.activeprod\$LOG_DIR/console.log21echo$!$PID_FILEechoApplication started with PID$(cat$PID_FILE)停止脚本 stop.sh#!/bin/bashPID_FILE/var/run/myapp.pidif[-f$PID_FILE];thenkill-15$(cat$PID_FILE)rm-f$PID_FILEechoApplication stopped.elseechoPID file not found.fi4.2 使用systemd实现服务化管理坑进程意外退出无人拉起开机不自启。正确做法创建systemd服务单元 /etc/systemd/system/myapp.service[Unit]DescriptionMy Java AppAfternetwork.target[Service]UserappuserWorkingDirectory/opt/appExecStart/usr/bin/java-jar/opt/app/app.jar--spring.profiles.activeprodSuccessExitStatus143RestartalwaysRestartSec10[Install]WantedBymulti-user.target启用并启动服务systemctl daemon-reload systemctlenablemyapp systemctl start myapp管理命令start|stop|restart|status自动日志记录journalctl -u myapp。5. 日志处理5.1 日志路径与滚动坑日志写入当前目录随运行时间增长撑爆磁盘无日志滚动排查问题困难。正确做法在 application.yml 中配置Logback或Log4j2将日志输出到指定目录并设置滚动策略logging: file: path: /var/log/myapp name: /var/log/myapp/app.log logback: rollingpolicy: max-history:30max-file-size: 100MB或使用外部日志框架配置并确保目录存在且应用用户有写权限。5.2 使用logrotate进行系统级轮转坑应用自身日志滚动失效时如错误配置可配合系统logrotate进行二次保障。正确做法创建 /etc/logrotate.d/myapp/var/log/myapp/*.log{daily rotate7compress delaycompress missingok notifempty copytruncate}6. 配置管理6.1 环境隔离坑开发、测试、生产配置混用导致生产连接测试数据库。正确做法使用Spring Profiles通过--spring.profiles.activeprod激活。配置文件命名application-dev.yml、application-prod.yml。敏感信息密码、密钥不应明文存储使用Jasypt加密或配置中心Apollo、Nacos。6.2 敏感信息保护坑数据库密码硬编码在配置文件泄露风险。正确做法使用环境变量替换spring.datasource.password${DB_PASSWORD}在启动脚本中通过export DB_PASSWORDxxx或systemd的Environment传入。或集成Vault、KMS等密钥管理服务。7. 监控与健康检查7.1 内置健康检查坑应用假死进程存在但无响应无法及时发现。正确做法Spring Boot Actuator暴露健康端点management.endpoints.web.exposure.includehealth,info management.endpoint.health.show-detailsalways使用curl定期检查curl-fhttp://localhost:8080/actuator/health||systemctl restart myapp配合监控系统Prometheus Grafana采集指标。7.2 进程监控坑进程意外崩溃无自动恢复。正确做法systemd的 Restartalways 可自动重启。或使用Supervisor等进程管理工具。8. JVM与Linux内核调优8.1 JVM参数配置坑默认堆内存过大或过小导致OOM或频繁GC。正确做法根据服务器内存和应用需求设置 -Xms、-Xmx通常设为相同值避免动态调整。选择合适的GC算法如G1并输出GC日志用于排查java-Xms2g-Xmx2g-XX:UseG1GC\-XX:PrintGCDetails-XX:PrintGCDateStamps\-Xloggc:/var/log/myapp/gc.log\-jarapp.jar注意GC日志文件也需要滚动。8.2 文件句柄限制坑高并发应用打开过多文件socket、文件达到系统默认1024限制报错 Too many open files。正确做法修改 /etc/security/limits.conf增加应用用户的nofileappuser soft nofile65536appuser hard nofile65536同时调整systemd服务中的 LimitNOFILE655368.3 内核参数调整坑网络连接数过高时端口耗尽或time_wait过多。正确做法调整TCP参数如 net.ipv4.ip_local_port_range、net.ipv4.tcp_tw_reuse 等具体视场景9. 常见坑点及解决方案问题现象可能原因解决方案启动后立即退出无错误日志缺少依赖、端口冲突、配置文件错误检查日志控制台或文件使用 21 重定向中文乱码系统编码非UTF-8启动参数加 -Dfile.encodingUTF-8并确保LANGen_US.UTF-8时区错误日志时间差8小时JVM时区未设置添加 -Duser.timezoneAsia/Shanghai 或设置TZ环境变量内存占用持续增长最终OOM内存泄漏使用JVM监控工具jstat、jmap、VisualVM分析堆转储无法绑定端口端口被占用netstat -tlnp上传JAR后启动提示“权限不足”JAR文件没有可读权限chmod r app.jarsystemd启动失败无详细日志systemd单元配置错误使用 systemctl status 查看错误或 journalctl -xe10. 总结将JAR包部署到Linux服务器绝非简单的 java -jar 命令而是一个涉及环境、配置、安全、运维的系统工程。通过以下原则可规避绝大多数坑点环境标准化使用与开发一致的JDK借助Docker容器实现环境一致性。配置外部化分离环境配置敏感信息加密。进程服务化使用systemd或类似工具管理生命周期实现自愈和自启动。日志集中化合理配置日志路径和滚动策略便于排查。监控全面化健康检查、指标采集、告警机制缺一不可。权限最小化使用专用用户运行严格控制文件权限。最后建议将部署过程脚本化、自动化Ansible、Jenkins Pipeline减少人为失误提升效率和可靠性。