????????需求描述: 写一个监控nginx的脚本;如果Nginx服务宕机,则该脚本可以检测到并将进程启动;如果正常运转,则不做任何处理。
1. 如何判断一个进程死掉了,分析思路如下:
# Mac 启动nginx服务
~ % sudo nginx
# 通过ps -ef命令查看服务是否存在,通过grep-v参数过滤掉执行查看命令时生成grep子进程
~ % ps -ef | grep nginx | grep -v grep
0 36127 1 0 11:04下午 ?? 0:00.00 nginx: master process nginx
-2 36128 36127 0 11:04下午 ?? 0:00.00 nginx: worker process
# $?返回值为0时,表示nginx进程正常
~ % echo $?
0
# Mac 关闭nginxfuwu
~ % sudo nginx -s quit
# 再次查看nginx服务无任何输出
~ % ps -ef | grep nginx | grep -v grep
# $?返回值为非0时,表示nginx进程已经死掉了
~ % echo $?
1
2. 编写守护进程常遇到坑
# 查看nginx进程是否存在
~ % ps -ef | grep nginx | grep -v "grep"
# $?返回值为非0,表示nginx服务已经停止
~ % echo $?
1
# 查看脚本内容中nginx服务进程查询命令
~ % cat 27.nginx_daemon.sh
#!/bin/bash
ps -ef | grep nginx | grep -v grep
echo $?
# 运行脚本,发现 $?返回值竟然不是0,这是为什么呢?
# 因为脚本名中包含nginx了,在执行 sh 27.nginx_daemon.sh这个命令的时候,
# 执行脚本本身也会作为一个子进程运行在系统中,又给grep出来。
~ % sh 27.nginx_daemon.sh
501 36216 36017 0 11:25下午 ttys000 0:00.01 sh 27.nginx_daemon.sh
0
# 给脚本修改名字,再次运行脚本,$?返回值不为0,充分验证了上述判断是正确的
~ % mv 27.nginx_daemon.sh 27_1.daemon.sh
~ % sh 27_1.daemon.sh
1
# 将脚本名重新改回去
~ % mv 27_1.daemon.sh 27.nginx_daemon.sh
????????如何处理因脚本名包含nginx时,导致“运行脚本包含查看进程命令”和“终端直接运行查看进程命令”,$?返回值不一致问题,解决思路如下:通过使用‘$$’命令进行过滤。
#!/bin/bash
# echo $$, 直接输出执行脚本过程产生的子进程的PID
this_pid=$$
# 通过“grep -v $this_pid”直接把自身执行的子进程过滤掉,
# 这样就可以不管脚本中起的名字包含什么字眼,只要你执行这个脚本的时候过滤掉,
# 从而可以使判断进程是否存在的执行命令做出正确判断
ps -ef | grep nginx | grep -v grep | grep -v $this_pid
echo $?
3. nginx守护进程代码实现
#!/bin/bash
#
# set password="XXX" # 预输入需要的密码
# echo $$, 直接输出执行脚本过程产生的子进程的PID
# 用来过滤脚本本身执行时启动子进程
# 常用于执行脚本传参为进程名称时,查看某个进程情况避免干扰
this_pid=$$
# 通过“grep -v $this_pid”直接把自身执行的子进程过滤掉,
# 这样就可以不管脚本中起的名字包含什么字眼,只要你执行这个脚本的时候过滤掉,
# 从而可以使判断进程是否存在的执行命令做出正确判断
while true
do
ps -ef | grep nginx | grep -v grep | grep -v $this_pid &>/tmp/null
if [ $? -eq 0 ];then
echo "Nginx is running well"
# 等待3s
sleep 3
else
# Mac 使用
sudo nginx
# systemctl start nginx
echo "Nginx is down, Start it ..."
fi
done
# 脚本运行结果
~ % sh 27.nginx_daemon.sh
Nginx is running well
Nginx is running well
Nginx is down, Start it ...
Nginx is running well
4. 使用nopub命令,让脚本运行日志不在前台输出并后台运行进程
# 通过nohup后台挂起运行程序,通过exit命令退出终端然后关闭shell,
# 注意:不能直接退出终端,要不后台无法挂起任务
# 直接输入以下命令,连续两次回车,进程开始在后台作为一个守护进程不停运行
~ % nohup sh 27.nginx_daemon.sh &
[1] 36623
~ % appending output to nohup.out
~ %
# 查看守护进程的日志输出
~ % tail -f nohup.out
Nginx is running well
Nginx is running well
Nginx is down, Start it ...
Nginx is running well
# nohup关闭后台程序
# 方式一:通过jobs -l查看进程PID,kill命令结束进程,
# 用于查看当前终端后台运行的任务,换了终端就看不到了
~ % jobs -l
[1] + 36623 running nohup sh 27.nginx_daemon.sh
~ % kill % 36623
[1] + terminated nohup sh 7.nginx_daemon.sh
~ % jobs -l
# 方式二:通过ps -ef查看进程PID,kill命令结束进程,
# 用于查看瞬间进程动态,可以看到别的终端后台运行
~ % ps -ef | grep "27.nginx_daemon.sh" | grep -v grep
501 37561 36017 0 12:39上午 ttys000 0:00.01 sh 27.nginx_daemon.sh
~ % kill % 37561
[1] + terminated nohup sh 27.nginx_daemon.sh
5. 其它判断服务是否正常运行场景
# 以下命令都可以作为进程是否存在判断条件等等,需要灵活运用
~ % netstart -tnlp | grep :80 # 如果进程存在时候就代表服务正常
zsh: command not found: netstart
~ % curl localhost/index.html # 获取到某个页面的值就认为服务正常
curl: (7) Failed to connect to localhost port 80: Connection refused
|