Java服务重启脚本(带日志归类功能)
以下是一个功能完善的Java服务重启脚本,包含日志归类、旧日志备份、进程检查等功能:
#!/bin/bash
# Java服务重启脚本
# 功能:停止旧服务、备份旧日志、启动新服务、日志归类
# 配置区 ========================================
SERVICE_NAME="my-java-service" # 服务名称
JAR_NAME="myapp.jar" # Java应用jar包名
JAVA_OPTS="-Xms2g -Xmx2g" # JVM参数
LOG_DIR="/var/log/${SERVICE_NAME}" # 日志目录
BACKUP_DIR="/var/log/${SERVICE_NAME}/backup" # 日志备份目录
PID_FILE="/var/run/${SERVICE_NAME}.pid" # PID文件位置
MAX_LOG_DAYS=30 # 日志保留天数
# ===============================================
# 创建目录
mkdir -p ${LOG_DIR}
mkdir -p ${BACKUP_DIR}
# 获取当前时间用于日志文件名
CURRENT_TIME=$(date "+%Y%m%d_%H%M%S")
# 1. 停止旧服务
stop_service() {
echo "正在停止服务 ${SERVICE_NAME}..."
if [ -f ${PID_FILE} ]; then
PID=$(cat ${PID_FILE})
if ps -p ${PID} > /dev/null; then
kill ${PID}
# 等待最多10秒让进程正常退出
for i in {1..10}; do
if ! ps -p ${PID} > /dev/null; then
break
fi
sleep 1
done
# 如果进程仍然存在,则强制杀死
if ps -p ${PID} > /dev/null; then
kill -9 ${PID}
echo "服务已被强制终止"
else
echo "服务已正常停止"
fi
rm -f ${PID_FILE}
else
echo "PID文件存在但进程不存在,删除PID文件"
rm -f ${PID_FILE}
fi
else
echo "PID文件不存在,尝试通过进程名查找..."
PID=$(ps -ef | grep ${JAR_NAME} | grep -v grep | awk '{print $2}')
if [ -n "${PID}" ]; then
kill ${PID}
echo "通过进程名找到并停止服务"
else
echo "服务未运行"
fi
fi
}
# 2. 备份旧日志
backup_logs() {
echo "备份旧日志..."
# 打包旧日志
if [ -n "$(ls ${LOG_DIR}/*.log 2>/dev/null)" ]; then
BACKUP_FILE="${BACKUP_DIR}/logs_${CURRENT_TIME}.tar.gz"
tar -czf ${BACKUP_FILE} -C ${LOG_DIR} *.log
echo "日志已备份到 ${BACKUP_FILE}"
# 删除原始日志文件
rm -f ${LOG_DIR}/*.log
else
echo "没有找到需要备份的日志文件"
fi
# 清理过期备份
find ${BACKUP_DIR} -name "*.tar.gz" -type f -mtime +${MAX_LOG_DAYS} -delete
echo "已清理超过${MAX_LOG_DAYS}天的日志备份"
}
# 3. 启动新服务
start_service() {
echo "正在启动服务 ${SERVICE_NAME}..."
# 定义日志文件路径
STDOUT_LOG="${LOG_DIR}/stdout_${CURRENT_TIME}.log"
GC_LOG="${LOG_DIR}/gc_${CURRENT_TIME}.log"
# 启动命令
nohup java ${JAVA_OPTS} \
-Dlogging.dir=${LOG_DIR} \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${GC_LOG} \
-jar ${JAR_NAME} > ${STDOUT_LOG} 2>&1 &
# 记录PID
echo $! > ${PID_FILE}
echo "服务已启动,PID: $(cat ${PID_FILE})"
echo "标准输出日志: ${STDOUT_LOG}"
echo "GC日志: ${GC_LOG}"
}
# 4. 检查服务状态
check_status() {
echo "检查服务状态..."
sleep 3 # 等待几秒让服务完全启动
if [ -f ${PID_FILE} ]; then
PID=$(cat ${PID_FILE})
if ps -p ${PID} > /dev/null; then
echo "服务运行正常 (PID: ${PID})"
# 检查端口是否监听(如果有特定端口)
# netstat -tlnp | grep ${PID}
return 0
else
echo "服务进程不存在!"
return 1
fi
else
echo "PID文件不存在!"
return 1
fi
}
# 主执行流程
echo "===== 开始重启 ${SERVICE_NAME} ====="
stop_service
backup_logs
start_service
check_status
if [ $? -eq 0 ]; then
echo "===== 服务重启成功 ====="
else
echo "===== 服务重启失败,请检查日志 ====="
exit 1
fi
使用说明
- 将上述脚本保存为
restart_java_service.sh
- 修改脚本开头的配置参数,特别是:
SERVICE_NAME
: 你的服务名称JAR_NAME
: 你的Java应用jar包名JAVA_OPTS
: JVM参数LOG_DIR
: 日志目录
- 给脚本执行权限:
chmod +x restart_java_service.sh
- 执行脚本:
./restart_java_service.sh
功能特点
-
完善的进程管理:
- 通过PID文件或进程名查找并停止旧服务
- 先尝试正常停止,超时后强制终止
-
日志管理:
- 自动备份旧日志到备份目录
- 按时间戳命名日志文件,方便追踪
- 自动清理过期日志备份
-
服务状态检查:
- 启动后自动检查服务状态
- 提供明确的成功/失败反馈
-
日志分类:
- 标准输出日志
- GC日志(如果启用GC日志选项)
- 可按需添加更多分类日志
-
配置灵活:
- 所有关键参数都在脚本开头集中配置
- 方便根据实际需求调整
您可以根据实际需求进一步调整此脚本,例如添加邮件通知、更详细的健康检查等功能。