一、守护进程
概念
- 守护进程是在后台运行的不受终端控制的进程,通常守护进程在系统启动时自动运行,守护进程的名称通常以d结尾,比如sshd、xinetd、crond等。
特点
- 后台常驻运行。
- 不会随着创建该守护进程的会话退出后,守护进程也跟着退出,要能 7x24 小时运行哇!
- 不能具有控制终端。杜绝从控制终端接收标准输入,还输出日志到控制终端。
进程管理工具
Linux系统提供了多种进程管理工具,常见的工具包括nohup、systemd、Upstart、Supervisor、SysVinit、Docker等。
二、守护进程的管理工具
接下来将介绍3中常用的进程管理工具的使用方法
2.1 nohup命令
- 简单粗暴方式
这种方式实现简单,但缺点也很明显,当进程退出后,无法自愈。
nohup command 2>&1 >> log &
2.2 supervisor
supervisor 是一个系统守护进程,它可以启动、停止和管理其他进程。它可以用于管理和监控长时间运行的进程,例如 Web 服务器、数据库服务器等。supervirsor管理进程会尝试进程自愈、设置日志输出与配置日志轮转等功能。supervisor 的配置文件通常位于 /etc/supervisor/conf.d/ 目录下,文件名通常以 .conf 结尾。在配置文件修改后,可以使用 supervisorctl 命令来管理进程。例如,使用 supervisorctl start myprogram 命令可以启动名为 myprogram 的进程,使用 supervisorctl stop myprogram 命令可以停止名为 myprogram 的进程。
supervisorctl 是 supervisor 进程控制系统的命令行客户端,它允许你通过命令行来管理和控制 supervisor 进程。
以下是一些基本的 supervisorctl 命令:
start : 启动指定的进程。
stop : 停止指定的进程。
restart : 重启指定的进程。
status: 显示所有进程的状态。
reread: 重新读取配置文件。
update: 根据最新的配置文件启动、停止或重启进程。
exit: 退出 supervisorctl。
案例实战-使用supervirsor管理node_exporter进程
利用supervirsor管理node_exporter进程
- 创建/etc/supervisor/conf.d/node_exporter.conf文件
[program:node_exporter]
command = /usr/local/bin/node_exporter --collector.filesystem.ignored-mount-points="^/(dev|proc|sys|mnt|var/lib/docker/.+)($|/)" --collector.textfile.directory=/usr/local/personalDebugKVM
autostart = true
autorestart = true
# 进程退出后,重试3次拉起进程
startretries = 3
# 启动进程的用户
user = root
# 日志输出
stdout_logfile = /var/log/supervisor/%(program_name)s.stdout.log
stderr_logfile = /var/log/supervisor/%(program_name)s.stderr.log
stdout_logfile_maxbytes = 300MB
stdout_logfile_backups = 10
stderr_logfile_maxbytes = 300MB
stderr_logfile_backups = 5
stopwaitsecs = 900
startsecs = 10
- 加载配置文件并拉起进程
root@ubuntu1604:~# supervisorctl reload
Restarted supervisord
root@ubuntu1604:~# supervisorctl status
node_exporter RUNNING pid 483992, uptime 0:00:13
- 测试故障自愈
root@ubuntu1604:~# ps aux |grep exporter
root 483992 0.1 0.0 718596 19240 ? Sl 22:00 0:00 /usr/local/bin/node_exporter --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|mnt|var/lib/docker/.+)($|/) --collector.textfile.directory=/usr/local/personalDebugKVM
root 484262 0.0 0.0 15964 968 pts/1 S+ 22:01 0:00 grep --color=auto exporter
root@ubuntu1604:~# kill -15 483992
root@ubuntu1604:~# supervisorctl status
node_exporter STARTING
root@ubuntu1604:~# supervisorctl status
node_exporter STARTING
root@ubuntu1604:~# supervisorctl status
node_exporter STARTING
# 可以看到进程被supervirsor重新拉起来了
root@ubuntu1604:~# date;supervisorctl status
Thu Aug 15 22:02:12 CST 2024
node_exporter RUNNING pid 484271, uptime 0:00:11
2.3 start-stop-daemon命令
在 Debian 系统中, start-stop-daemon 就是为将一个普通程序变成守护进程而生。
参数 | 参数 | 作用 |
---|---|---|
-S | –start | 启动程序 |
-K | –stop | 给程序发信号,终止程序或者判断程序的状态都可以 |
-p | –pidfile | 在启动程序时将守护进程启动后的 pid 写入指定文件,方便后续的终止程序或者判断程序的状态 |
-m | –make-pidfile | 在启动程序时将守护进程启动后的 pid 写入指定文件,方便后续的终止程序或者判断程序的状态 |
-b | –backgroud | 通过 fork 和 setsid 的形式将程序变为后台运行。 |
-q | –quiet | 只显示错误信息 |
-d | –chdir | 更改进程的工作目录 |
-u | –user | 设置进程的执行用户 |
-k | –umask | 设置新建文件的权限掩码 |
因为有了 start-stop-daemon 可以很容易写出系统启动脚本,网上的例子很多,比如这个 https://gist.github.com/alobato/1968852#file-start-stop-example-sh
。
案例实战-puppetmaster多实例方式脚本
puppetmaster默认是单进程方式启动,当slave节点超过上百台后,会导致单进程压力过大而无法响应,维持可以将单进程改造为多进程方式。利用haprox+多进程puppetmaster,实现横向性能扩张,下面介绍如何用update-rc.d管理一个多进程版的puppetmaster的程序puppetmm
- 编辑脚本/etc/init.d/puppetmm
#!/bin/bash
### BEGIN INIT INFO
# Provides: mpuppetmaster
# Required-Start: $network $named $remote_fs $syslog
# Required-Stop: $network $named $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mutilprocess puppet master
# Description: The puppet master accepts connections from puppet agents,
# compiles manifests into catalogs for them, acts as a file
# server and report server.
# Author: xianwei in oppo
### END INIT INFO
# puppet master of multiprocess
set -e
# Must be a valid filename
NAME="puppet master of multiprocess"
PIDFILE_PRE="/var/run/puppet/puppetmaster.pid"
#This is the command to be run, give the full pathname
DAEMON="/usr/bin/ruby /usr/bin/puppet master"
DAEMON_OPTS="--daemonize --ssl_client_header=HTTP_X_SSL_SUBJECT "
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin:/usr/bin"
case "$1" in
start)
echo "Starting daemon: "$NAME
for port in `seq 8141 8149`
do
echo "Starting daemon: "$NAME masterport: ${port}
[ ! -f ${PIDFILE_PRE}${port} ] && \
${DAEMON} --pidfile=${PIDFILE_PRE}${port} --masterport=${port} $DAEMON_OPTS
done
echo "."
;;
stop)
echo "Stopping daemon: "$NAME
for port in `seq 8141 8149`
do
echo "Stopping daemon: "$NAME masterport: ${port}
start-stop-daemon --stop --signal HUP --quiet --pidfile ${PIDFILE_PRE}${port}
done
echo "."
;;
status)
ps aux |grep -E "puppetmaster.pid81[45][0-9]"
;;
*)
echo "Usage: "$1" {start|stop|status}"
exit 1
esac
exit 0
- 将脚本程序设置为系统服务
# 实现puppetmm进程的开机启动
update-rc.d puppetmm default 99
# 查看状态
root@ubuntu1604:~# /etc/init.d/puppetmm status
puppet 25131 9.4 2.1 6800788 2844848 ? Ssl Jul24 3059:40 /usr/bin/ruby /usr/bin/puppet master --pidfile=/var/run/puppet/puppetmaster.pid8153 --masterport=8153 --daemonize --ssl_client_header=HTTP_X_SSL_SUBJECT
puppet 25864 9.9 2.1 6343896 2849828 ? Ssl Jul24 3204:29 /usr/bin/ruby /usr/bin/puppet master --pidfile=/var/run/puppet/puppetmaster.pid8154 --masterport=8154 --daemonize --ssl_client_header=HTTP_X_SSL_SUBJECT
puppet 26216 8.9 2.2 6537676 2964004 ? Ssl Jul24 2897:35 /usr/bin/ruby /usr/bin/puppet master --pidfile=/var/run/puppet/puppetmaster.pid8155 --masterport=8155 --daemonize --ssl_client_header=HTTP_X_SSL_SUBJECT
....输出略
# 其他管理命令
/etc/init.d/puppetmm start
/etc/init.d/puppetmm stop
# 如果要移除服务
update-rc.d -f puppetmm remove