1. 用途

运行在服务器上的一些组件服务,比如大数据的 hadoop、hive、hbase,或者是自己写的一些需要长时间运行的程序,我们启动了之后,是不会经常去观察这些程序的运行状态的。正常情况下这是没问题的,但有时候,程序在运行过程中,会由于机器的负载,或者是其他的一些环境不稳定因素,到会程序停止运行。如果我们没有设计什么监控的话,只能在出现问题时,登录机器查看组件或程序运行的情况,这是非常被动的,如果影响到业务,会更严重,所以我们需要增加一些组件或程序运行的监控、报警和失败重启脚本。

2. 方案

2.1. supervisor

这是一种很成熟的方案,只需要按照人家的格式新建或修改配置文件就行。

不过我的机器上都部署了 CDH,而且 CDH 里面内置了 supervisor,所以自己再安装一份 supervisor 的话,涉及到修改配置文件之类的,会有一些风险,所以我们舍弃了这种方案。

2.2. shell脚本+crontab

另一种方案就是编写 shell 脚本,然后配置到 crontab 里面。

2.2.1. 监控脚本

下面是监控程序运行情况,并在失败时触发钉钉报警、重启程序的代码实例,脚本文件名为 service-monitor.sh

#!/bin/bash

# 在脚本最开头,加载一下 profile 文件,如果下面需要启动程序用到了 java,脚本最开头没有加载 profile 文件的话,会找不到 java 环境,然后无法启动对应的服务,而且还不会报错。
source /etc/profile

# cloudera-scm-server 服务运行检测
pid=$(ps -ef | grep 'cloudera-scm-server' | grep -v grep | awk '{print $2}')

if [ -z  "$pid" ]; then
	# 钉钉报警,按照钉钉官网进行钉钉群机器人创建、发送 post 请求即可。
    curl 'https://oapi.dingtalk.com/robot/send?access_token=xxx' \
    -H 'Content-Type: application/json' \
    -d '{"msgtype": "text","text": {"content":"运行服务报警:hadoop01 节点上 cloudera-scm-server 服务进程不存在"}}'

    echo -e "`date +'%Y-%m-%d %H:%M:%S'`  未检测到 cloudera-scm-server 服务,开始重启"
    # 这儿是启动对应服务的脚本
    systemctl start cloudera-scm-server
    echo -e "`date +'%Y-%m-%d %H:%M:%S'`  cloudera-scm-server 服务重启完成"

else
    echo -e "`date +'%Y-%m-%d %H:%M:%S'`  成功检测到 cloudera-scm-server 服务"
fi

echo -e ""

exit 0

一定要给脚本文件添加可执行权限:

chmod +x service-monitor.sh

下面是设置的 crontab 代码示例,每 10 秒执行一次脚本:

# 自动检测机器上的组件角色运行情况并重启挂掉的服务
*/1 * * * *             sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log
*/1 * * * * sleep 10 && sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log
*/1 * * * * sleep 20 && sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log
*/1 * * * * sleep 30 && sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log
*/1 * * * * sleep 40 && sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log
*/1 * * * * sleep 50 && sh /root/script/service-monitor.sh &>> /root/script/service-monitor.log

需要注意,里面所有的文件,都必须是绝对路径。

2.2.2. 日志清理脚本

由于上面配置的 crontab,把脚本运行的日志全部写入了日志文件,如果不定时清理,日志文件会一直增长。

#!/bin/bash
 
rm -f /root/script/service-monitor-week.log
 
mv /root/script/service-monitor.log /root/script/service-monitor-week.log
 
exit 0

然后配置 crontab:

# 每周周一清理上面监控脚本的日志文件
0 0 * * MON sh /root/script/log-clear.sh

可以从 crontab guru 这个网站根据提示生成自己的 crontab 表达式来定时调用日志清理脚本。