跳到主要内容

Linux 安全重启 Java JAR:优雅停止、PID 管理与启动检查

· 阅读需 2 分钟
Apache王也道长
软件开发者与技术作者

在 Linux 服务器上部署可执行 JAR 后,经常需要通过脚本完成停止、启动和重启。一个可靠的重启脚本应避免误杀其他 Java 进程,并优先让应用优雅退出。

基础重启脚本

下面以 test-1.0.jar 为例:

#!/usr/bin/env bash

APP_NAME="test-1.0.jar"
APP_DIR="$(cd "$(dirname "$0")" && pwd)"
LOG_FILE="$APP_DIR/run.log"
PID_FILE="$APP_DIR/app.pid"

cd "$APP_DIR" || exit 1

if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")

if kill -0 "$PID" 2>/dev/null; then
echo "Stopping $APP_NAME, PID=$PID"
kill "$PID"

for i in $(seq 1 30); do
if ! kill -0 "$PID" 2>/dev/null; then
break
fi
sleep 1
done

if kill -0 "$PID" 2>/dev/null; then
echo "Graceful shutdown timed out, forcing stop"
kill -9 "$PID"
fi
fi

rm -f "$PID_FILE"
fi

nohup java \
-server \
-Xms512m \
-Xmx512m \
-jar "$APP_NAME" \
--spring.profiles.active=test \
>> "$LOG_FILE" 2>&1 &

NEW_PID=$!
echo "$NEW_PID" > "$PID_FILE"

sleep 2
if kill -0 "$NEW_PID" 2>/dev/null; then
echo "Started successfully, PID=$NEW_PID"
else
echo "Start failed, check $LOG_FILE"
exit 1
fi

保存为 restart.sh 后添加执行权限:

chmod +x restart.sh
./restart.sh

为什么使用 PID 文件

使用 ps | grep 按名称查找进程可能匹配到多个程序,也可能匹配到命令本身。启动时把 $! 写入 PID 文件,可以准确记录当前脚本启动的进程。

不过,PID 可能在程序异常退出后被系统复用。因此脚本执行前还应结合应用目录、启动参数或服务管理器进一步确认。

为什么不直接使用 kill -9

kill PID 默认发送 SIGTERM,Java 应用可以执行关闭钩子,释放端口、关闭线程池并处理尚未完成的任务。

kill -9 会立即终止进程,应用没有清理资源的机会,所以只应作为优雅停止超时后的最后手段。

查看启动日志

tail -f run.log

如果启动失败,可以重点检查:

  • JAR 文件名称和工作目录是否正确。
  • Java 版本是否满足应用要求。
  • 服务端口是否被其他进程占用。
  • spring.profiles.active 指定的配置是否存在。
  • 当前用户是否具有目录和日志文件写入权限。

生产环境建议

长期运行的 Java 服务更适合交给 systemd、Supervisor 或容器平台管理。这些工具支持开机启动、失败重启、日志管理和服务状态检查,比手写脚本更容易维护。

本文阅读量:--

总访问量 -- · 访客数 --