4557 字
9 分钟
Java 服务守护方案:脚本自动化 + Systemd + Cron
企业级 Java 服务守护方案:脚本自动化 + Systemd + Cron
在生产环境中,Java 应用的稳定性至关重要。本文将介绍如何通过 Shell 脚本控制、Systemd 进程守护 以及 Crontab 定时任务,构建一套闭环的自动化运维体系。
方案架构图
graph TD
%% 节点定义
User((管理员/Cron)) -->|1. crontab 02:30| Systemd[Systemd 守护进程]
User -->|2. 手动维护| Script[start_app.sh 脚本]
subgraph "守护与监控层"
Systemd -->|ExecStart| Script
CronCheck[Cron * * * * *] -->|check-auto| Script
end
subgraph "执行层"
Script -->|启动/重启| JavaApp[Java 应用: zhjc-admin.jar]
Script -->|检查状态/重载| Nginx[Nginx 反向代理]
end
subgraph "反馈层"
JavaApp -->|异常崩溃| Systemd
Systemd -->|Restart=on-failure| Script
JavaApp -->|标准输出| Log[(java_app.log)]
end
1. 自动化控制脚本 (start_app.sh)
脚本是所有操作的基础。一个合格的启动脚本应该具备环境检查、PID 管理和状态反馈功能。
#!/bin/bash
# 路径: /home/admin/start_app.sh
# 基础配置
BASE_DIR="/home/admin"
JAVA_DIR="$BASE_DIR/java"
JAR_NAME="zhjc-admin.jar"
JAVA_PORT="8111"
# 启动 Java 函数
start_java() {
echo "[INFO] 正在启动 Java 应用..."
cd "$JAVA_DIR"
JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -Dfile.encoding=UTF-8"
# 使用 nohup 后台运行
nohup java $JVM_OPTS -jar $JAR_NAME --server.port=$JAVA_PORT > java_app.log 2>&1 &
NEW_PID=$!
echo $NEW_PID > java_app.pid
sleep 3
if ps -p $NEW_PID > /dev/null; then
echo "[INFO] Java 启动成功 (PID: $NEW_PID)"
else
echo "[ERROR] Java 启动失败"
return 1
fi
}
# 停止应用函数
stop_app() {
echo "[INFO] 正在停止应用..."
PID=$(pgrep -f "$JAR_NAME")
if [ ! -z "$PID" ]; then
kill $PID && sleep 2
kill -9 $PID 2>/dev/null
fi
}
# 自动检查逻辑 (用于 Cron)
check_auto() {
if ! pgrep -f "$JAR_NAME" > /dev/null; then
echo "[WARN] 检测到服务异常,正在重启..."
start_java
fi
}
case "$1" in
start) start_java ;;
stop) stop_app ;;
restart) stop_app && sleep 2 && start_java ;;
check-auto) check_auto ;;
*) echo "Usage: $0 {start|stop|restart|check-auto}" ;;
esac
脚本功能说明
| 命令 | 功能描述 |
|---|---|
start |
启动 Java 应用,配置 JVM 参数,记录 PID |
stop |
优雅停止应用,先发送 SIGTERM,再强制 SIGKILL |
restart |
先停止后启动,确保服务完全重启 |
check-auto |
检查进程状态,异常时自动重启(供 Cron 调用) |
2. Systemd 进程守护 (zhjc.service)
Systemd 是 Linux 的系统管理器。通过配置 Type=forking,我们可以让系统监控由脚本拉起的后台进程。
配置文件路径: /etc/systemd/system/zhjc.service
[Unit]
Description=ZHJC Admin Service
# 确保在网络和Nginx准备好后再启动
After=network.target nginx.service
[Service]
Type=forking
User=root
WorkingDirectory=/home/admin
ExecStart=/home/admin/start_app.sh start
ExecStop=/home/admin/start_app.sh stop
# 核心配置:崩溃后 10 秒自动重启
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
管理命令
# 重载配置
systemctl daemon-reload
# 开机自启
systemctl enable zhjc
# 立即启动
systemctl start zhjc
# 查看状态
systemctl status zhjc
# 停止服务
systemctl stop zhjc
# 查看日志
journalctl -u zhjc -f
Systemd 配置说明
| 配置项 | 说明 |
|---|---|
Type=forking |
服务以后台进程方式运行 |
Restart=on-failure |
服务异常退出时自动重启 |
RestartSec=10 |
重启前等待 10 秒 |
After=network.target |
确保网络就绪后再启动 |
3. Cron 定时清理与监控
最后,我们利用 Cron 实现定时"体检"和定时重启,防止内存溢出或僵尸进程。
配置命令: crontab -e
# 1. 每分钟执行一次"静默检查",如果进程没了自动拉起
* * * * * /home/admin/start_app.sh check-auto >> /home/admin/auto_monitor.log 2>&1
# 2. 每天凌晨 02:30 准时重启服务,释放内存
30 2 * * * systemctl restart zhjc
Cron 任务说明
| 定时规则 | 任务 | 目的 |
|---|---|---|
* * * * * |
每分钟检查进程状态 | 服务异常时自动恢复 |
30 2 * * * |
每天凌晨 2:30 重启 | 释放内存,防止长期运行堆积 |
总结:为什么要这么做?
| 层级 | 组件 | 解决的问题 | 核心价值 |
|---|---|---|---|
| 第一层 | 脚本化 | 规范启动参数 | 避免手动输入命令出错,标准化部署流程 |
| 第二层 | Systemd 守护 | 进程意外崩溃 | 自动重启,提供标准化日志接口(journalctl) |
| 第三层 | Cron 定时 | 长期运行内存积压 | 定时重启保持系统清爽,健康检查自动恢复 |
这三者结合,构成了一个多层级、可自我修复的运维环境。
快速部署指南
# 1. 上传脚本到服务器
scp start_app.sh admin@server:/home/admin/
ssh admin@server "chmod +x /home/admin/start_app.sh"
# 2. 配置 Systemd
scp zhjc.service admin@server:/tmp/
ssh admin@server "sudo mv /tmp/zhjc.service /etc/systemd/system/"
ssh admin@server "sudo systemctl daemon-reload"
ssh admin@server "sudo systemctl enable zhjc"
# 3. 配置 Cron
ssh admin@server "crontab -l > /tmp/cron_backup 2>/dev/null || true"
ssh admin@server "echo '* * * * * /home/admin/start_app.sh check-auto >> /home/admin/auto_monitor.log 2>&1' | sudo crontab -"
ssh admin@server "echo '30 2 * * * systemctl restart zhjc' | sudo crontab -"
# 4. 启动服务
ssh admin@server "sudo systemctl start zhjc"
ssh admin@server "sudo systemctl status zhjc"
希望这篇博客对你有帮助!如果你有更好的优化建议,欢迎在评论区交流。
Java 服务守护方案:脚本自动化 + Systemd + Cron
https://www.zztzz.com.cn/posts/50/ 部分信息可能已经过时









