2025 最新 | Linux 下 Java Jar 包后台运行与进程守护全攻略(从新手到生产必备)

阿白
发布于 2025-12-03 / 11 阅读
0
0

2025 最新 | Linux 下 Java Jar 包后台运行与进程守护全攻略(从新手到生产必备)

2025 最新 | Linux 下 Java Jar 包后台运行与进程守护全攻略(从新手到生产必备)

你是不是也经历过这些“崩溃瞬间”:

  • 😭 SSH 一断开,辛苦跑了好几个小时的 Jar 包直接挂掉?
  • 😡 凌晨 3 点被群里疯狂 @,上线修复的却是“进程莫名消失”?
  • 🤯 用 nohup java -jar xxx.jar & 以为万事大吉,结果第二天早上发现日志停在昨天,磁盘还被 nohup.out 撑爆了……

别慌!今天这篇文章彻底帮你解决这个问题。我们将一次性讲透 6 种方式,从最原始的命令到生产环境推荐方案,附带完整对比表 + 最佳实践 + 一键启动脚本


一、6 种方式对比表格(先看这个就懂了)

方式 命令关键点 SSH 断开后存活 日志管理 开机自启 适合场景 推荐指数
方式1 直接运行 ❌ 否 屏幕输出 ❌ 否 本地调试 ★☆☆☆☆
方式2 & 后台 ❌ 否 屏幕输出 ❌ 否 临时测试 ★★☆☆☆
方式3 nohup ✅ 是 差 (nohup.out) ❌ 否 个人测试、临时任务 ★★★☆☆
方式4 nohup + 重定向 ✅ 是 好 (自定义路径) ❌ 否 传统服务器、中型项目 ★★★★☆
方式5 screen / tmux ✅ 是 极好 (会话保持) ❌ 否 需要频繁交互/看日志 ★★★★★
方式6 Systemd 服务 ✅ 是 完美 (journalctl) 支持 所有生产环境 ★★★★★★★

二、详细讲解(强烈建议从方式 4 开始看)

❌ 方式 1 & 2:最原始的两种(只适合本地玩玩)

# 方式1:前台运行,窗口被锁定,Ctrl+C 即停止
java -jar app.jar

# 方式2:加个 & 后台运行
java -jar app.jar &

致命缺点: 当你关闭终端或 SSH 断开连接时,会话会发送 SIGHUP 信号,导致进程直接被杀。结论:永远不要在服务器上这么干!

⚠️ 方式 3:经典 nohup 的“坑”

很多人习惯这么写:

nohup java -jar app.jar &

这种写法有三大隐患:

  1. 日志灾难: 所有输出(System.out)默认写入当前目录的 nohup.out,文件会无限增长,甚至占满磁盘空间。
  2. 错误丢失: 如果没有正确重定向 stderr,异常堆栈信息可能不会被记录,导致排查问题两眼一抹黑。
  3. 管理混乱: 多个 Jar 包混用一个 nohup.out,根本分不清谁是谁。

✅ 方式 4:nohup 的正确打开方式(2025 推荐写法)

# 先创建日志目录
mkdir -p logs

# 4.1 标准生产写法(推荐)
# 解释:
# > logs/app.log  : 标准输出重定向到文件
# 2>&1            : 错误输出(2) 也重定向到标准输出(1) 去
# &               : 后台运行
nohup java -Xms512m -Xmx2g -jar app.jar > logs/app.log 2>&1 &

# 4.2 按启动时间命名日志
# 注意:这只会在启动那一刻生成带日期的文件名,它不会每天自动切割!
nohup java -jar app.jar > logs/app-$(date +%F).log 2>&1 &

# 4.3 “静默”模式(不需要看日志,或者程序内部集成了 Logback/Log4j)
nohup java -jar app.jar > /dev/null 2>&1 &

🛠️ 方式 5:神器级 screen / tmux(运维最爱)

如果你需要经常连上去看控制台日志,或者需要手动输入指令交互,这两个工具是神器。它们创建了一个**“永不掉线”的虚拟终端**。

tmux 用法(比 screen 更现代化,推荐)

# 1. 创建一个叫 "myapp" 的会话
tmux new -s myapp

# 2. 在里面正常启动 Java
java -jar app.jar

# 3. 哪怕你直接关掉 SSH 窗口,程序也在跑
# 4. 下次上线,一键找回现场:
tmux attach -t myapp

🚀 方式 6:生产环境终极方案 —— Systemd 托管(强烈推荐)

别再写脚本了!用 Linux 自带的 Systemd,不仅能开机自启,还能挂了自动重启

第一步:创建服务文件
sudo vim /etc/systemd/system/myapp.service

第二步:填入标准配置

[Unit]
Description=My Java Application
After=syslog.target network.target

[Service]
Type=simple
# 强烈建议使用非 root 用户运行
User=root
# 项目根目录
WorkingDirectory=/opt/myapp
# 启动命令 (请换成你 java 的绝对路径,可用 `which java` 查看)
ExecStart=/usr/bin/java -Xms1g -Xmx2g -jar /opt/myapp/app.jar
# 停止命令
ExecStop=/bin/kill -15 $MAINPID
# Java 进程通常以 143 状态码退出,需标记为成功,否则 Systemd 会报错
SuccessExitStatus=143
# 进程崩溃后自动重启
Restart=always
RestartSec=10
# 日志输出到 systemd journal
StandardOutput=journal
StandardError=journal
# 增加文件句柄限制
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

第三步:享受正规军的待遇

# 重新加载配置
sudo systemctl daemon-reload

# 启动服务
sudo systemctl start myapp

# 设置开机自启
sudo systemctl enable myapp

# 查看实时日志(比 tail -f 强大得多,支持时间过滤)
sudo journalctl -u myapp -f

三、实用加分技巧

1. 快速查找 Java 进程

别只知道 ps -ef 了,试试这些高效命令:

# 最精准:列出 Java 进程的完整包名
jps -l

# 最现代:根据端口查进程
ss -ltnp | grep 8080

2. 通用启动/停止脚本 (Shell)

如果你不想用 Systemd,这个脚本可以存为 run.sh,配合 Jenkins 或手动发布很方便。这里使用了更稳健的 pgrep 来获取 PID。

#!/bin/bash
# 配置区
APP_NAME=shareniu.jar
APP_PATH=/opt/shareniu
LOG_FILE=$APP_PATH/logs/app.log

# 检查 PID (使用 pgrep -f 更精准,防止 grep 到脚本自己)
PID=$(pgrep -f $APP_NAME)

start() {
    if [ -n "$PID" ]; then
        echo "❌ $APP_NAME 正在运行 (PID: $PID)"
    else
        mkdir -p $APP_PATH/logs
        nohup java -Xms1g -Xmx2g -jar $APP_PATH/$APP_NAME > $LOG_FILE 2>&1 &
        echo "✅ $APP_NAME 已启动"
    fi
}

stop() {
    if [ -n "$PID" ]; then
        kill -15 $PID
        echo "🛑 已发送停止信号给 $APP_NAME (PID: $PID)"
    else
        echo "⚠️ $APP_NAME 未运行"
    fi
}

case "$1" in
    start) start ;;
    stop)  stop ;;
    restart) stop; sleep 3; start ;;
    status) 
        if [ -n "$PID" ]; then echo "🟢 运行中 (PID: $PID)"; else echo "⚪ 未运行"; fi 
        ;;
    *) echo "用法: $0 {start|stop|restart|status}" ;;
esac

四、总结与建议

你的场景 推荐方案
本地开发/调试 直接 IDE 运行 或 命令行直连
个人服务器/小工具 tmux (最方便) 或 nohup
公司生产环境 Systemd (唯一正解)
Docker/K8s 容器 方式 1 (直接 java -jar,必须前台运行)

2025 年了,答应我:
如果是正式的 Linux 服务器,尽量抛弃 nohup,拥抱 Systemd。它提供的崩溃重启开机自启日志管理能力,能让你少熬很多个通宵!

你们公司现在用哪种方式跑 Jar 包?是还在坚持 nohup,还是已经全面容器化了?欢迎评论区交流~

点赞 + 收藏,下次部署服务时不迷路!🚀


评论