已复制
全屏展示
复制代码

CentOS7安装daemontools与supervise的使用总结


· 7 min read

一. 工具介绍

daemontools 工具官网介绍 http://cr.yp.to/daemontools.html

daemontools 工具需要root权限,所以直接切换到root用户进行安装。daemontools是svscanboot,svscan,supervise,svc,svok,svstat等一系列工具的合集。其中,supervise 是其中的核心工具。

二. 工具安装

  • 下载解压
sudo su -

mkdir -p /opt/package
chmod 1755 /opt/package
cd /opt/package


wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
tar -zxf daemontools-0.76.tar.gz
cd admin/daemontools-0.76/
  • 还不能直接编译,需要修改代码文件
vim src/conf-cc
# 在gcc 一行末尾增加
-include /usr/include/errno.h

# 更改后
gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -include /usr/include/errno.h
  • 编译安装
cd /opt/package/admin/daemontools-0.76/
./package/install

...
Copying commands into ./command...
Creating symlink daemontools -> daemontools-0.76...
Making command links in /command...
Making compatibility links in /usr/local/bin...
Creating /service...
Adding svscanboot to inittab...
init should start svscan now.


# 安装完成之后,会创建 /service和 /command两个目录
[root@node1 daemontools-0.76]# ll /service/
total 0
[root@node1 daemontools-0.76]# 
[root@node1 daemontools-0.76]# 
[root@node1 daemontools-0.76]# ll /command
total 0
lrwxrwxrwx 1 root root 45 May 20 12:11 envdir -> /opt/package/admin/daemontools/command/envdir
lrwxrwxrwx 1 root root 48 May 20 12:11 envuidgid -> /opt/package/admin/daemontools/command/envuidgid
lrwxrwxrwx 1 root root 45 May 20 12:11 fghack -> /opt/package/admin/daemontools/command/fghack
lrwxrwxrwx 1 root root 47 May 20 12:11 multilog -> /opt/package/admin/daemontools/command/multilog
lrwxrwxrwx 1 root root 47 May 20 12:11 pgrphack -> /opt/package/admin/daemontools/command/pgrphack
lrwxrwxrwx 1 root root 52 May 20 12:11 readproctitle -> /opt/package/admin/daemontools/command/readproctitle
lrwxrwxrwx 1 root root 46 May 20 12:11 setlock -> /opt/package/admin/daemontools/command/setlock
lrwxrwxrwx 1 root root 48 May 20 12:11 setuidgid -> /opt/package/admin/daemontools/command/setuidgid
lrwxrwxrwx 1 root root 48 May 20 12:11 softlimit -> /opt/package/admin/daemontools/command/softlimit
lrwxrwxrwx 1 root root 48 May 20 12:11 supervise -> /opt/package/admin/daemontools/command/supervise
lrwxrwxrwx 1 root root 42 May 20 12:11 svc -> /opt/package/admin/daemontools/command/svc
lrwxrwxrwx 1 root root 43 May 20 12:11 svok -> /opt/package/admin/daemontools/command/svok
lrwxrwxrwx 1 root root 45 May 20 12:11 svscan -> /opt/package/admin/daemontools/command/svscan
lrwxrwxrwx 1 root root 49 May 20 12:11 svscanboot -> /opt/package/admin/daemontools/command/svscanboot
lrwxrwxrwx 1 root root 45 May 20 12:11 svstat -> /opt/package/admin/daemontools/command/svstat
lrwxrwxrwx 1 root root 45 May 20 12:11 tai64n -> /opt/package/admin/daemontools/command/tai64n
lrwxrwxrwx 1 root root 50 May 20 12:11 tai64nlocal -> /opt/package/admin/daemontools/command/tai64nlocal


# 查看是否加入自启动,在最后一行会看到启动svscanboot的配置
cat /etc/inittab

SV:123456:respawn:/command/svscanboot
  • 启动 svscanboot, svscanboot是自动加入了自启动脚本了的,所以只需要手动启动一次即可。svscanboot会随系统启动而启动,svscanboot 会启动 svscan 监视 /service 目录,svscan 则为 /service 的每个进程都启动一个 supervise 服务(也就是后面提到的的supervise testprogram)。
/command/svscanboot &

ps aux | grep svs
root      93653  0.0  0.0 113184  1420 pts/1    S    12:28   0:00 /bin/sh /command/svscanboot
root      93655  0.0  0.0   4396   468 pts/1    S    12:28   0:00 svscan /service

三. 使用示例

下面使用普通用户 yzy 启动服务,需要提前设置 yzy 用户 sudo 免密。

  • 1、创建主程序目录/home/yzy/testprogram,编写主程序/home/yzy/testprogram/testprogram.py,内容如下
import time
while True:
    print("running..",time.time())
    time.sleep(10)
  • 2、创建启动脚本,并给出执行权限 vim /home/yzy/testprogram/runchmod +x /home/yzy/testprogram/run,脚本内容如下
#!/bin/bash
cd /home/yzy/testprogram/
exec python -u testprogram.py >> /tmp/logs 2>&1
  • 3、启动程序。也就是创建一个软连接,这样启动的程序是以root权限启动的。
sudo ln -s /home/yzy/testprogram /service


ps aux | grep testprogram
root       3323  0.0  0.0   4224   436 ?        S    17:10   0:00 supervise testprogram
root       4038  0.0  0.0  23972  4632 ?        S    17:54   0:00 python -u testprogram.py
yzy        4050  0.0  0.0 112712   968 pts/0    R+   17:54   0:00 grep --color=auto testprogram
  • 4、确保普通用户也能使用svc svstat等命令,切换到root用户修改 sudoers 配置
sudo su -
visudo
# 确保 /usr/local/bin 在里面
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

四. 常用命令

由于这个服务是root用户启动的,所以需要使用 sudo 或者切换到 root 才能执行相关命令。如果 cd 到程序目录/home/yzy/testprogram,那么 /service/testprogram 可以替换成 . 也就说不用写绝对路径。

sudo svc -u  /service/testprogram      # 启动服务
sudo svc -d  /service/testprogram      # 停止服务
sudo svc -o  /service/testprogram      # 只启动一次服务
sudo svc -k  /service/testprogram      # 杀掉服务,杀掉后会立即被启动

svstat /service/testprogram # 查看服务状态

五. 普通用户权限启动服务

前面我们创建服务(创建软连接)的时候使用了sudo,也就是root权限启动服务的,有些服务时不允许root服务启动的,所以来看看怎么使用普通用户权限启动服务。

只需要在 exec 后面加上 /usr/local/bin/setuidgid yzy 即可指定用户启动程序了。下面是指定 yzy 用户启动程序的示例

#!/bin/bash

cd /home/yzy/testprogram/
exec /usr/local/bin/setuidgid yzy python -u testprogram.py >> /tmp/logs 2>&1

六. 启动前、停止后分别执行脚本

有时为了监控命令的执行是否停止,是否启动,想在启动脚本的前后分别发送消息。如果只是简单的在 exec 这一行的前面、后面分别加入执行脚本,你会发现后面的脚步不能执行了。如果你去掉exec,你会发现正常了,但是使用 svc -d 不能停止服务了。

原因是 exec 命令会让新的命令替换掉当前的shell脚本,所以一旦执行了 exec ,后面的内容就不会执行了,详情见exec的详细用法:https://yuchaoshui.com/731c133/

  • 错误示例 run 脚本:后面的脚本不会执行
#!/bin/bash
cd /home/yzy/testprogram/
./send_ding.py starting_program
exec /usr/local/bin/setuidgid yzy python -u testprogram.py >> /tmp/logs 2>&1
./send_ding.py stopping_program
  • 正确示例 run 脚本:下面是部署 rembg 服务的示例,由于运行 rembg 会启动新的shell,即新的 pid,supervise 监控的是 run 脚本的 pid ,所以当 run 被通知退出时,要手动把 rembg 的 pid 杀掉。
#!/bin/bash
cd /opt/rembg
./venv/bin/python ding_alarm.py starting_rembg
./venv/bin/rembg s -t 5 -p 5000 >>./logs/logs_`date '+%Y%m%d%H'` 2>&1 &
REMBG_PID=$!
trap "./venv/bin/python ding_alarm.py rembg_stopped; kill $REMBG_PID" EXIT
wait $REMBG_PID

七. 日志切换

前面的示例中,如果不重启程序,日志永远都打印在一个文件中,daemontools提供了 multilog 来自动切换日志。看下面示例:

#!/bin/bash

cd /home/yzy/testprogram/
exec python -u testprogram.py 2>&1 | multilog t n10 s1000 ./logs

上面 的示例中:

  • 程序 testprogram.py 的所有输出(标准错误、标准输出)都输入到 multilog,有multilog来统一处理日志
  • t  表示在每一行日志前面加上时间戳,比如@4000000065b24d5605e27a34,转换为可读时间字符串方法:echo @4000000065b24cdf0fd440f4.s | tai64nlocal
  • n10 表示保留最新的10个日志文件
  • s1000  表示每个日志文件最大存放1000字节
  • ./logs  用于存放日志文件,不能自定义文件名的前缀,文件名以时间戳命名
ll logs/
total 40
-rwxr--r-- 1 root root 2114 Jan 25 19:56 @4000000065b24c60321138fc.s
-rwxr--r-- 1 root root 2122 Jan 25 19:56 @4000000065b24c7234d4c9b4.s
-rwxr--r-- 1 root root 2121 Jan 25 19:56 @4000000065b24c8437843244.s
-rwxr--r-- 1 root root 2118 Jan 25 19:57 @4000000065b24c963a9c2c5c.s
-rwxr--r-- 1 root root 2117 Jan 25 19:57 @4000000065b24ca903aa8f7c.s
-rwxr--r-- 1 root root 2119 Jan 25 19:57 @4000000065b24cbb084f53b4.s
-rwxr--r-- 1 root root 2120 Jan 25 19:57 @4000000065b24ccd0b760b3c.s
-rwxr--r-- 1 root root 2118 Jan 25 19:58 @4000000065b24cdf0fd440f4.s
-rwxr--r-- 1 root root 2121 Jan 25 19:58 @4000000065b24cf11456331c.s
-rw-r--r-- 1 root root 1768 Jan 25 19:58 current
-rw------- 1 root root    0 Jan 25 18:44 lock
-rw-r--r-- 1 root root    0 Jan 25 18:44 state

# 时间戳转换为可读时间戳方法
echo @4000000065b24cdf0fd440f4.s | tai64nlocal
2024-01-25 19:58:13.265568500.s

注意:这样写有一个缺点,由于使用了管道,启动程序的pid不在是原本的主程序,所以此时 svc -d 来停止程序是不行的。

🔗

文章推荐