最近在研究linux系统的整机快速备份与恢复,已经确定文件可以完整备份并恢复成功,但一些服务是否可以正常运行还不能确定,所以有了下面的尝试
- 首先写了一个系统运行所依赖的服务的保活脚本
- 在系统服务目录 /usr/lib/systemd/system 中新建一个服务,用来保持此脚本的运行
Shell脚本
文件名: swp-service-stay-active.sh
文件存放位置: /root/
# ! /bin/sh
export LANG="en_US.UTF-8"
SERVICE_NAMES=(mysqld.service nginx.service php-fpm.service redis-server.service)
LOG_FILE="/root/swp-service-stay-active.log"
echo `date +%Y-%m-%d` `date +%H:%M:%S` "服务保护程序已启动" >>$LOG_FILE
while true
do
RUNNING_SERVICES=`systemctl --type=service | grep running`
for SERVICE in ${SERVICE_NAMES[*]}; do
if [[ $RUNNING_SERVICES =~ $SERVICE ]]; then
:
# echo `date +%Y-%m-%d` `date +%H:%M:%S` "服务" $SERVICE "已启动" >>$LOG_FILE
else
systemctl restart $SERVICE
echo `date +%Y-%m-%d` `date +%H:%M:%S` "重启服务" $SERVICE >>$LOG_FILE
fi
done
sleep 30 # 每30秒检查一轮
done
字段描述
# ! /bin/sh 设定脚本执行语言(必需项)
export LANG="en_US.UTF-8" # 解决中文乱码问题
SERVICE_NAMES # 所守护的服务名称
LOG_FILE # log文件名称及所在位置
# 逻辑:每隔30s获取一次正在运行的服务列表(str格式),判断所守护的服务是否在其中,在其中时不做任何操作,不在其中时重启此服务,并记录日志
系统服务
文件名: swp-service-stay-active.service
[Unit]
Description=Swp-ServiceStayActive
After=network.target
Wants=mysqld.service nginx.service php-fpm.service redis-server.service
[Service]
Type=forking
ExecStartPre=/bin/sleep 10s
ExecStart=/bin/bash -c 'nohup sh /root/swp-service-stay-active.sh >/dev/null 2>&1 &'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStartSec=30s
KillMode=control-group
Restart=always
RestartSec=5s
PrivateTmp=true
[Install]
WantedBy=multi-user.target
字段描述
[Unit]
# 服务名称,可自定义
Description=Swp-ServiceStayActive
# 等待网络启动后再开启服务
After=network.target
# 存在弱关联关系的服务,上述服务是否启动对此服务的启动无影响
Wants=mysqld.service nginx.service php-fpm.service redis-server.service
[Service]
# 后台运行
Type=forking
# 开启服务前做的操作:等待10s,让守护服务先启动
ExecStartPre=/bin/sleep 10s
# 开启服务命令,/bin/bash为bash执行程序的绝对路径,-c表示后续""中的命令将作为一条命令执行
ExecStart=/bin/bash -c "nohup sh /root/swp-service-stay-active.sh >dev/null 2>&1 &"
# 重启服务命令
ExecReload=/bin/kill -s HUP $MAINPID
# 结束服务命令,此处可使用QUIT、TERM、9来结束进程,主进程结束后会同时结束相关子进程
ExecStop=/bin/kill -s QUIT $MAINPID
# 启动服务超时时间
TimeoutStartSec=30s
# 关闭服务时关闭所有相关联进程
KillMode=control-group
# 除stop命令外任何情况下关闭服务服务都将重启
Restart=always
# 服务重启间隔时间
RestartSec=5s
# 服务是否使用私有的tmp目录(必需项,未设置时启动服务会出错)
PrivateTmp=true
[Install]
# 服务组开机自启
WantedBy=multi-user.target
操作
-
上传文件
使用ftp工具上传文件 (上传到/root文件夹下)
-
授予文件读写执行权限
chmod 777 swp-service-stay-active.sh chmod 777 swp-service-stay-active.service
-
移动文件目录
cd /root mv swp-service-stay-active.service /usr/lib/systemd/system
-
设置开机启动
cd /usr/lib/systemd/system systemctl enable swp-service-stay-active.service
-
重新加载文件
systemctl daemon-reload
-
启动服务
systemctl start swp-service-stay-active.service
移除服务
-
结束服务
systemctl stop swp-service-stay-active.service
-
取消开机启动
systemctl disable swp-service-stay-active.service
-
删除服务
rm -rf swp-service-stay-active.service
-
重新加载文件
systemctl daemon-reload
其他命令
-
查看服务状态
systemctl status swp-service-stay-active.service
-
查看服务日志
journalctl -u swp-service-stay-active.service
-
重启服务
systemctl restart swp-service-stay-active.service
-
查看正在运行的服务
systemctl --type=service | grep running
另:如果shell脚本中使用了java运行脚本,则必须指定java绝对路径
(此处尝试在脚本中使用which java获取java绝对路径,未能成功获取)
例如:
# ! /bin/sh
SERVICE_PATH="/home"
SERVICE_LIST=(swp-exchange.jar swp-exchange-edit.jar)
SERVICE_URL="http://backend.swpiot.local/ews/ewsConfig"
LOG_FILE="/home/swp_exchange_active.log"
#JAVA_PATH=`which java`
JAVA_PATH="/usr/java/jdk1.8.0_321/bin/java"
cd $SERVICE_PATH
while true
do
for SERVICE in ${SERVICE_LIST[*]}; do
procnum=`ps -ef | grep $SERVICE | grep -v grep | wc -l`
echo `date +%Y-%m-%d` `date +%H:%M:%S` $SERVICE "进程数:" $procnum >>$LOG_FILE
if [ $procnum -eq 0 ];then
if [ $SERVICE == "swp-exchange.jar" ];then
nohup $JAVA_PATH -jar $SERVICE -uc $SERVICE_URL -dc 180 -si 120000 -sm 1 >/dev/null 2>&1 &
echo `date +%Y-%m-%d` `date +%H:%M:%S` "启动进程:" $SERVICE >>$LOG_FILE
else
nohup $JAVA_PATH -jar $SERVICE -uc $SERVICE_URL >/dev/null 2>&1 &
echo `date +%Y-%m-%d` `date +%H:%M:%S` "启动进程:" $SERVICE >>$LOG_FILE
fi
elif [ $procnum -gt 1 ];then
echo `date +%Y-%m-%d` `date +%H:%M:%S` "当前程序:" $SERVICE "占用进程数:" $procnum >>$LOG_FILE
pkill -f $SERVICE
echo `date +%Y-%m-%d` `date +%H:%M:%S` "已结束进程:" $SERVICE >>$LOG_FILE
fi
done
sleep 120 # 每120秒检查一轮
done