“Better code, better life. ”
Monit介绍
Monit
是一个管理和监视进程,程序,文件,目录和Unix系统上的文件系统的工具。使用Monit
我们可以很方便的进行自动运维,并可以在程序发生错误的情况下执行一些自定义的操作。Monit
可以启动一个不运行的进程,重启一个没有响应的进程,停止一个使用了太多资源的进程。可以使用Monit
来监视文件、执行各种TCP/IP
网络检查、SSL
协议检查、目录和文件系统的变化,比如时间戳的变化、校验和的变化化等等,可谓功能丰富。
安装与配置
安装与测试
#centos/redhat
sudo yum install monit -y
#ubuntu
sudo apt-get install monit
monit服务需要配置文件monitrc来运行,monit安装后有一个默认的配置文件在
/var/monit/monitrc
目录下。
测试运行
$monit -t
$Control file syntax OK
运行
$monit -c /var/monit/monitrc
start-stop-daemon安装
我这边部署的monit服务底层是依赖于start-stop-daemon这个工具的,当然也可以用其他的守护进程工具替代
#CentOS 6.5
wget http://ftp.de.debian.org/debian/pool/main/d/dpkg
tar -xf dpkg_1.16.18.tar.xz && cd dpkg_1.16.18
./configure
# configure: error: no curses library found
yum install ncurses-devel -y
./configure && make
sudo make install
which start-stop-daemon # 查看start-stop-daemon位置
启动选项
monit可以通过加载
monitrc
文件里的配置信息运行,也可以直接通过命令行参数运行
[-c] monitrc
文件目录
[-d] n 每多少秒检查一次;等于在monitrc文件中加set daemon
[-g] name 对某个分组进行统一操作
[-i] file 设置日志输出文件;等于在monitrc文件中加set log
[-p] pidfile 在守护进程模式下使用此锁文件;等于在monitrc文件中加set pidfile
[-s] statefile monit状态信息文件;等于在monitrc文件中加set statefile
[-B] 批量命令行指令;等于在monitrc文件中加set terminal batch
[-I] 禁用后台运行模式;等于在monitrc文件中加set init
[-t] 对monitrc
文件做语法检查
monit控制文件
monit通过写控制文件设置监控什么服务?如何监控?等内容,其中监控的对象包括进程、文件、磁盘、目录、远程主机、系统、网络等九种类型,本文我们的重点是对进程的监控。
控制文件格式
监控进程的控制文件一定要有的一行命令是这样的:
CHECK PROCESS <unique name> <PIDFILE <path> | MATCHING <regex>>
path
是进程pidfile
的绝对路径,如果pidfile
不存在,或者pidfile
内不包含process id
,monit会执行控制文件的START语句。
regex
是使用PID文件的替代方案,可以使用进程名模式匹配来查找要监视的进程。
示例
下面是一个简单的控制文件quote_monitor.monitrc
,它命名了一个服务名quote_monitor
,以及该服务的pidfile
路径
CHECK PROCESS quote_monitor PIDFILE /data/monit_daemon/pidfile.d/quote_monitor.pid
START = "/data/monit_daemon/bin/monit_start_daemon.sh /home/quote_monitor/quote_monitor"
STOP = "/data/monit_daemon/bin/monit_stop_daemon.sh"
GROUP svc
GROUP svc.quote_monitor
# 若进程不存在, `告警`并`重启`
IF NOT EXIST THEN EXEC "/data/monit_daemon/bin/monit_wechat_notify.sh" ELSE IF SUCCEEDED THEN EXEC "/data/monit_daemon/bin/monit_wechat_notify.sh"
IF NOT EXIST THEN RESTART
# 连续5次都重启失败, `告警`
# IF 5 RESTART 5 CYCLES THEN EXEC "/data/monit_daemon/bin/monit_alert_to_dingtalk.sh"
第一行是标准格式CHECK PROCESS
段,下面定义了一些动作。
START
当monit检查不到该进程的pid时会执行
STOP
当执行monit stop
或者monit stop all
时会执行
GROUP
指定当前进程的分组,monit [option] -g [group name]
在下面是一个简单的IF exp THEN statment
逻辑判断,指定服务异常停止后的动作。
其他脚本
monitrc配置文件
# 每10秒检测一次
set daemon 10
# 日志
set log /var/log/monit.log
# pid文件
set pidfile /var/run/monit.pid
# state数据文件
# set statefile ~/.monit.state
# MODE:
# ACTIVE (默认) // 主动监控 (挂了后重启恢复)
# PASSIVE // 被动监控 (挂了不重启)
#
# 为了避免每次reload带来批量重启进程的影响
# 在发布过程中, 更新完monit目录的代码后
# 手工将PASSIVE模式打开, 然后再做reload (这样的话短暂时间内monit只是会触发告警但是并不会重启程序)
#
#MODE PASSIVE
# ONREBOOT:
# START (默认) // monit重启后监控项也重启
# NOSTART // monit重启后监控项不重启
# LASTSTATE // monit重启后进程的启动状态同monit重启前一致
SET ONREBOOT LASTSTATE
set httpd port 2812
allow localhost
set eventqueue basedir /var/monit slots 1000
#包含所有子配置项
include /data/monit_daemon/enabled__conf.d/*.monitrc
include /data/monit_daemon/enabled__conf.d/*/*.monitrc
admin.sh
#!/bin/bash
_CUR_DIR=$(cd $(dirname "${BASH_SOURCE[0]}" ) >/dev/null && pwd )
# 保证是root用户在执行
user_name=$(id -un) #whoami
if [ "$user_name" != "root" -a "$1" != "force_stop" -a "$1" != "status" -a "$1" != "ps" ] ; then #如果是force_stop/status/ps, 则不一定是root用户
echo "Error: You should use root user!"
exit 100
fi
_RC_FILE=/root/.monitrc
_PIDFILE=/var/run/monit.pid
# 修正配置文件的权限, 保证 _RC_FILE 有效
chown root. ${_CUR_DIR}/monitrc
chmod 600 ${_CUR_DIR}/monitrc
ln -sf ${_CUR_DIR}/monitrc ${_RC_FILE}
# 保证 pidfile.d/ 目录有效
mkdir -m 1777 -p /data/monit_daemon/pidfile.d/
chmod 1777 /data/monit_daemon/pidfile.d/
#操作start,stop
case "$1" in
start)
monit -c ${_RC_FILE}
;;
reload)
monit reload
;;
status)
ps -ef | grep -v -w grep | grep -w monit || echo 'monit not found!!!'
lsof -i -Pn -Tqs -a -c monit | grep -E 'LISTEN|$'
netstat -tlpnee | grep -F ":2812" || echo 'listen 2812 not found!!!'
echo
monit summary
;;
stop)
start-stop-daemon -v --oknodo --pidfile ${_PIDFILE} --stop
;;
force_stop)
start-stop-daemon -v --oknodo --pidfile ${_PIDFILE} --retry 'TERM/5/KILL/3' --stop
;;
restart)
start-stop-daemon -v --oknodo --pidfile ${_PIDFILE} --stop && sleep 2
monit -c ${_RC_FILE}
;;
*)
echo $"Usage: $0 {start|reload|status|stop|force_stop|restart} "
exit 2
esac
上面是monit服务的启停脚本,注意脚本中加载*.monitrc
文件的目录。
monit_start_daemon.sh
#!/bin/bash
_CUR_DIR=$(cd $(dirname "${BASH_SOURCE[0]}" ) >/dev/null && pwd )
source ${_CUR_DIR}/../export_dot_env.sh
if [ -z "${MONIT_SERVICE}" ] ; then
echo "MONIT_SERVICE empty!"
exit 99
fi
# MONIT_SERVICE=<unique_name> monit_start_daemon.sh <executable> ...arguments
_UNIQUE_NAME=${MONIT_SERVICE}
_STARTAS=$1
shift 1
_PIDFILE=/data/monit_daemon/pidfile.d/${_UNIQUE_NAME}.pid
_LOG_DIR=/data/logs/_console_/${_UNIQUE_NAME}/$(/bin/date '+%Y%m%d_') #%H%M%S
mkdir -m 775 -p -v ${_LOG_DIR} || exit 106 #664权限保证同一group的用户可以写
# 允许生成任意大小的coredump文件
ulimit -c unlimited
# 启动进程
/usr/local/bin/start-stop-daemon -v --oknodo --pidfile ${_PIDFILE} --chdir ${PWD:-/} --background --no-close --make-pidfile --startas ${_STARTAS} --start -- "$@" >> ${_LOG_DIR}/stdout.log 2>> ${_LOG_DIR}/stderr.log
exit $?
monit_stop_daemon.sh
#!/bin/bash
_CUR_DIR=$(cd $(dirname "${BASH_SOURCE[0]}" ) >/dev/null && pwd )
source ${_CUR_DIR}/../export_dot_env.sh
if [ -z "${MONIT_SERVICE}" ] ; then
echo "MONIT_SERVICE empty!"
exit 99
fi
# MONIT_SERVICE=<unique_name> monit_stop_daemon.sh
_UNIQUE_NAME=${MONIT_SERVICE}
_PIDFILE=/data/monit_daemon/pidfile.d/${_UNIQUE_NAME}.pid
/usr/local/bin/start-stop-daemon -v --oknodo --pidfile ${_PIDFILE} --remove-pidfile --stop
exit $?
有上面三个脚本以后,就可以启动一个服务了。至于monit_wechat_notify.sh和monit_alert_to_dingtalk.sh这两个脚本就不贴了,可以替换成自己用的告警脚本。
目录结构
所有的监控服务的文件都放在了/data/monit_deamon
目录下,下面是该目录的结构
├── admin.sh
├── bin
│ ├── monit_start_daemon.sh
│ ├── monit_stop_daemon.sh
│ └── monit_wechat_notify.sh
├── conf.d
│ └── quote_monitor.monitrc
├── enabled__conf.d
│ ├── ctp_collector.monitrc
│ └── quote_monitor.monitrc
├── monitrc
├── pidfile.d
│ ├── ctp_collector.pid
│ └── quote_monitor.pid
├── test.py
操作参数
monit服务启动以后,daemon进程会在本地开启一个TCP服务,默认监听2812端口(可自定义配置)。可以通过monit命令或者web服务来管理监控服务。
-
start all
启动控制文件中列出的所有服务,并启用对它们的监视。
-
start [name]
启动指定服务,并启用对它的监视。
-
stop all
停止所有服务
-
stop [name]
停止指定服务
-
restart all
重启所有服务
-
restart [name]
重启指定服务
-
unmonitor all
取消对所有服务器的监控,取消以后进程异常终止也不会触发指定事件。
-
unmonitor [name]
取消对指定服务的监控
-
status [name]
查看指定服务的运行状态,如果不加参数,则查看所有服务的信息,包括一些进程的基本信息、运行时间等
-
summary [name]
查看运行信息摘要,如果不加参数则查看所有服务的信息。
-
report [up down initialising unmonitored total]
报告服务状态。如果没有选项,则输出Monit管理的所有服务状态的简短概述。选项up打印处于此状态的所有服务的数量,down同样打印,依此类推。
-
reload
重新加载monitrc文件,重启deamon进程。
-
quit
结束deamon进程
-
validate
检查控制文件中列出的所有服务。这个动作也是Monit在守护进程模式下运行时的默认行为。
-
procmatch [regex]
允许对进程匹配检查的模式进行简单的测试。该命令接受正则表达式作为参数,并显示与模式匹配的所有运行进程。