我正在开发一个主要启动系统是 runit 的系统。
不幸的是,runit 要求它运行的任何应用程序都在前台运行,如下所示:
#!/bin/bash
exec sshd -D
由于 nginx 没有提供在前台运行它的方法,我怎样才能让 runit 仍然管理 nginx 并能够使用 runit 的sv
命令停止、启动和重新启动它?
答案1
您可以使用选项daemon off
:
exec /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;"
从Nginx 维基:
您可以使用 runit / daemontools 在生产模式下安全地使用 daemon off,但是您无法进行正常升级。 master_process off 不应该在生产中使用。
当您使用runit
control时nginx
,它成为主进程的父进程nginx
。但是,如果您尝试进行在线升级,nginx
主进程将分叉并执行新的二进制文件。
创建了一个新的 master 进程,但是因为旧的 master 进程仍然存在(因为它由 控制runit
),所以新的 master 进程的父进程将是 init 进程,因为runit
无法控制新的 master 主进程,因为它没有启动它。
答案2
不要关闭现实世界中使用的任何东西的主进程,它不会进行零停机升级并且不受支持。
使用页面哨兵监控端口 80 等以正确的方式进行操作,不要包含一些神奇的内容,否则 nginx 无法进行零停机升级,你会看起来像一个业余爱好者。
# . . .
set -e
## config - start - should move to another file
CONF='/etc/nginx/nginx.conf'
# TODO: grab below by parsing CONF
PROTO=http
IP=0.0.0.0
PORT=80
## config - end - should move to another file
case "$(uname | tr '[A-Z]' '[a-z]')" in
darwin|freebsd|netbsd|openbsd) NC_ARGS="-n -w 5 -z '${IP}' '${PORT}'" ;;
linux) NC_ARGS="-n -w 5 --send-only '${IP}' '${PORT}'" ;;
*) echo "unsupported os $(uname)" >&2; exit 1 ;;
esac
/usr/bin/nginx -t -c "${CONF}"
/usr/bin/nginx -c "${CONF}"
sleep 5
while /usr/bin/nc $NC_ARGS </dev/null >/dev/null 2>&1; do
set -e # loop runs in a subshell
/usr/bin/curl -m5 -fsS -A 'runit script/0.0.0' \
"${PROTO}"://"${IP}":"${PORT}" | \
/usr/bin/grep -q 'This comment is required'
sleep 2
done