我正在尝试将多个 Zope 实例配置为 FreeBSD 中的守护进程。每个实例都有一个启动脚本/usr/local/etc/rc.d。启动工作正常,但调用状态或停止会出现问题,因为正在运行的实例的 PID 会混淆(尽管 PID 不同,但启动脚本无法区分它们)。
这是 rc 脚本的模板:
instancename="%%instancename%%"
name="$instancename"
rcvar="${name}_enable"
zope="/usr/local/opt/zope"
python="${zope}/bin/python"
command_interpreter="$python"
command="${zope}/bin/runwsgi -v /usr/local/www/zope-instances/${instancename}/etc/zope.ini -d"
start_cmd="/usr/sbin/daemon -u myuser $command"
load_rc_config "$name"
run_rc_command $*
“%%”之间的值对于每个实例设置不同。
当我尝试获取状态或停止进程(service instancename status
或service instancename stop
)时,将使用最后启动的实例的 PID。对于能够创建 pid 文件的进程,情况并非如此,但我需要的脚本 runwsgi 不会创建 pid 文件。
我明白那个进程名,默认为命令变量,用于区分进程,但我不知道如何根据我的需要正确设置它。
答案1
我认为您走在正确的道路上,但您期望 rc 框架自动处理比实际更多的事情。
看起来你可能很熟悉BSD 中的实用 rc.d 脚本当你谈到:
例如,stop 必须知道进程的 PID 才能终止它。在本例中,rc.subr(8) 将扫描所有进程的列表,查找名称等于 $procname 的进程。后者是 rc.subr(8) 的另一个有意义的变量,其值默认为 command 的值。换句话说,当我们设置command时,procname实际上被设置为相同的值。
如果您承认自己没有“简单”的守护进程,并使用以下内容查看下一部分,您的生活将会变得更加轻松“高级”守护进程。因此,与其设置procname
正确的名称以便扫描 PID,不如简单地设置 PID 文件。pidfile
是一个已知实体rc.subr(8)明白了。
您正在使用守护进程与终端分离并很好地处理 pid 文件。
所以如果你添加:
pidfile="/var/run/${name}.pid"
并改变你的start_cmd
:
start_cmd="/usr/sbin/daemon -P ${pidfile} -u myuser $command"
那么你应该可以走了。
另一篇概述简单 rc 脚本的好文章是Go 守护进程的受监督 FreeBSD rc.d 脚本- 它的要点很简单:
#!/bin/sh
#
# PROVIDE: goprogram
# REQUIRE: networking
# KEYWORD:
. /etc/rc.subr
name="goprogram"
rcvar="goprogram_enable"
goprogram_user="goprogram"
goprogram_command="/usr/local/goprogram/goprogram"
pidfile="/var/run/goprogram/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f ${goprogram_command}"
load_rc_config $name
: ${goprogram_enable:=no}
run_rc_command "$1"
请注意主要区别在于它们控制 pid 文件而不是依赖$procname