在上一篇文章中,我们使用docker部署了Prometheus,使用nohup的方式启动了node_exporter,但是并没有对此程序设置开机自启动,各种原因都会造成服务器重启,所以必须添加,常规的开机自启动以后再说,这里我们先来看看另外一个工具,Supervisor。
上一篇文章:Docker部署Prometheus与Grafana - SPEX

Supervisor简介

Supervisord 是用 Python 实现的一款的进程管理工具,supervisord 要求管理的程序是非 daemon 程序,supervisord 会帮你把它转成 daemon 程序,因此如果用 supervisord 来管理进程,进程需要以非daemon的方式启动。

例如:管理nginx 的话,必须在 nginx 的配置文件里添加一行设置 daemon off 让 nginx 以非 daemon 方式启动。

Supervisor安装

# 安装
yum install -y supervisor

# 启动自启动
systemctl start supervisord
systemctl enable supervisord

# 查看配置文件,可以看到包含/etc/supervisord.d/下的ini文件
cat /etc/supervisord.conf | grep -v ';'

···
[include]
files = supervisord.d/*.ini
···

Supervisor说明

Supervisor安装后有两个可用命令supervisord supervisorctl,我们主要使用后者来管理使用supervisor启动的服务。

Supervisorctl

  • supervisorctl stop programxxx,停止某一个进程(programxxx),programxxx 为[program:beepkg] 里配置的值,这个示例就是 beepkg。
  • supervisorctl start programxxx,启动某个进程。
  • supervisorctl restart programxxx,重启某个进程。
  • supervisorctl status,查看进程状态。
  • supervisorctl stop groupworker ,重启所有属于名为 groupworker 这个分组的进程(start,restart 同理)。
  • supervisorctl stop all,停止全部进程,注:start、restart、stop 都不会载入最新的配置文件。
  • supervisorctl reload,载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程。
  • supervisorctl update,根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启。

Supervisor配置文件

这里直接拿node_exporter的配置文件来看。

cat /etc/supervisord.d/node_exporter.ini 

[program:node_exporter] ;程序名称
directory=/node_exporter ;程序启动目录
command=/node_exporter/node_exporter ;程序启动命令
user=root ;程序启动用户
autostart=true ;是否跟随supervisor自启动
autorestart=true ;是否在出错的时候自动重新启动
startsecs=30 ;程序启动时间,30秒内没有异常则认为启动成功
startretries=5 ;启动失败后重启尝试的次数
redirect_stderr=true ;将错误日志重定向至out,默认false
stdout_logfile_maxbytes=20MB ;out日志默认大小,默认为50MB
stdout_logfile=/var/log/supervisor/out_node_exporter.log ;out日志输出目录
# stderr_logfile=/var/log/supervisor/err_node_exporter.log ;错误日志输出目录
# 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
# environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

去除掉说明的配置文件:

[program:node_exporter]
directory=/node_exporter
command=/node_exporter/node_exporter
user=root
autostart=true
autorestart=true
startsecs=30
startretries=5
redirect_stderr=true
stdout_logfile_maxbytes=20MB
stdout_logfile=/var/log/supervisor/out_node_exporter.log

Supervisor管理服务

在配置文件完成后,直接运行supervisorctl update载入最新文件,然后使用supervisorctl status查看服务状态,因为我们设置了启动时间为30秒,所以在30秒如果没有错误的话,状态应该显示为STARTING。

请不要使用systemctl restart supervisordsupervisorctl reload来重新加载,因为这样都会重启supervisor,会造成其他的服务重启。


制作成脚本

本脚本可采用Nginx进行发布,然后利用curl ip/文件 | sh方式运行。

#!/bin/bash
# install epel
checkepel=$(rpm -qa | grep epel | awk '{print $1}' | cut -c 1-4)
if [ "$checkepel" != epel ];then
    echo "Now install epel..."
    yum install -q -y epel-release
    yum makecache
fi
# install sshpass supervisor
yum install -q -y sshpass supervisor lsof
systemctl enable supervisord
systemctl start supervisord
# mkdir
if [ ! -d /node_exporter ];then
    mkdir /node_exporter
fi
# download node_exporter
if [ ! -f /node_exporter/node_exporter ];then
    sshpass -p 密码 scp -o "StrictHostKeyChecking no" root@ip:/node_exporter/node_exporter /node_exporter
fi
# vi node.ini
cat <<EOF >/etc/supervisord.d/node_exporter.ini
[program:node_exporter]
directory=/node_exporter
command=/node_exporter/node_exporter
user=root
autostart=true
autorestart=true
startsecs=30
startretries=5
redirect_stderr=true
stdout_logfile_maxbytes=20MB
stdout_logfile=/var/log/supervisor/out_node_exporter.log
EOF
# supervisor update
supervisorctl update
# firewalld
checkport=$(firewall-cmd --query-port=9100/tcp)
if [ "$checkport" == "no" ];then
    echo "Port 9100 is not opened...Adding it"
    firewall-cmd --add-port=9100/tcp --permanent
    firewall-cmd --reload
else
    echo "Port 9100 is opened now!"
fi

#finish
checkstatus=$(lsof -i:9100 | grep LISTEN | awk '{print $1}' | cut -c 1-4)
if [ "$checkstatus" == "node" ];then
    echo "Waitting for supervisor's information..."
    seconds_left=30
    echo "Please wait ${seconds_left} s..."
    while [ $seconds_left != "0" ];do
        echo -n $seconds_left
        sleep 1
        seconds_left=$(($seconds_left - 1))
        echo -ne "\r \r"
    done
    checksupervisor=$(supervisorctl status | grep node_exporter | awk '{ print $2}')
    if [ "$checksupervisor" == 'RUNNING' ];then
        echo "Node_exporter is RUNNING!!!"
    fi
fi
Last modification:July 2nd, 2019 at 02:04 pm