【问题标题】:exit all supervisord processes if one exited如果一个退出,退出所有supervisord进程
【发布时间】:2016-08-28 14:17:09
【问题描述】:

我有一个我希望的 docker 图像:
- 运行乘客服务器和另一个用于监控乘客服务器的守护程序。
- 一旦这两个进程中的任何一个进程退出一次,容器就会退出。
- 将所有日志定向到标准输出

在配置文件中,我放置了一个事件监听器(参考:https://serverfault.com/questions/760726/how-to-exit-all-supervisor-processes-if-one-exited-with-0-result/762406#762406),它为乘客监控程序捕获一些事件并执行脚本 tt.sh。

我可以看到 1 个额外的 Passenger_monit 程序实例正在生成并在几次尝试后达到 FATAL 状态。其他的passenger_monit 和passenger_server 都很好。其他passenger_monit 的事件没有到达事件监听器。

这些是没有按预期工作的脚本:

这是supervisord.conf

[supervisord]

nodaemon=true
stdout_logfile=/dev/fd/1
redirect_stderr=true
stdout_logfile_maxbytes=0

[unix_http_server]
file=%(here)s/supervisor.sock

[supervisorctl]
serverurl=unix://%(here)s/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[program:passenger_monit]

command=./script/passenger_monit.sh
process_name=passenger_monit
startretries=999
redirect_stderr=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
autorestart=true
killasgroup=true
stopasgroup=true
numprocs=1

[program:passenger_server]

command=passenger start
startretries=999
redirect_stderr=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
autorestart=true
killasgroup=true
stopasgroup=true
numprocs=1

[eventlistener:passenger_monit_exit]
command=./tt.sh
process_name=passenger_monit
events=PROCESS_STATE_STARTING,PROCESS_STATE_EXITED,PROCESS_STATE_FATAL
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0

这是./script/passenger_monit.sh

#!/bin/bash

set -x

cd /passenger/newrelic_passenger_plugin/

# if exec is not put, then this process is not killed when supervisord exits
exec ./newrelic_passenger_agent

set +x

这是tt.sh

#!/bin/bash
echo "in tt!"

这是我运行的命令:

docker exec -it -u deploy 56bbbbe4352b  supervisord

这是我得到的输出:

2016-08-26 19:47:29,369 INFO RPC interface 'supervisor' initialized
2016-08-26 19:47:29,369 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2016-08-26 19:47:29,370 INFO supervisord started with pid 2446
2016-08-26 19:47:30,374 INFO spawned: 'passenger_monit' with pid 2452
2016-08-26 19:47:30,377 INFO spawned: 'passenger_server' with pid 2453
in tt!
2016-08-26 19:47:30,392 INFO exited: passenger_monit (exit status 0; not expected)
=============== Phusion Passenger Standalone web server started ===============
PID file: /home/deploy/abc/tmp/pids/passenger.3000.pid
Log file: /home/deploy/abc/log/passenger.3000.log
Environment: development
Accessible via: http://0.0.0.0:3000/

You can stop Phusion Passenger Standalone by pressing Ctrl-C.
Problems? Check https://www.phusionpassenger.com/library/admin/standalone/troubleshooting/
===============================================================================
2016-08-26 19:47:31,565 INFO spawned: 'passenger_monit' with pid 2494
2016-08-26 19:47:31,566 INFO success: passenger_server entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
in tt!
2016-08-26 19:47:31,571 INFO exited: passenger_monit (exit status 0; not expected)
2016-08-26 19:47:33,576 INFO spawned: 'passenger_monit' with pid 2498
in tt!
2016-08-26 19:47:33,583 INFO exited: passenger_monit (exit status 0; not expected)
2016-08-26 19:47:36,588 INFO spawned: 'passenger_monit' with pid 2499
in tt!
2016-08-26 19:47:36,595 INFO exited: passenger_monit (exit status 0; not expected)
2016-08-26 19:47:37,597 INFO gave up: passenger_monit entered FATAL state, too many start retries too quickly


^C2016-08-26 19:47:47,730 WARN received SIGINT indicating exit request
2016-08-26 19:47:47,735 INFO waiting for passenger_server to die
Stopping web server... done
2016-08-26 19:47:47,839 INFO stopped: passenger_server (exit status 2)

这是supervisorctl status的输出

passenger_monit                  STOPPED    Not started
passenger_monit_exit:passenger_monit FATAL      Exited too quickly (process log may have details)
passenger_server                 RUNNING    pid 2453, uptime 0:00:14

supervisord -v的输出

3.0b2

【问题讨论】:

标签: docker supervisord


【解决方案1】:

以下应该有效。请注意,10 秒脚本将在 5 秒后被终止。

[supervisord]
loglevel=warn
nodaemon=true

[program:hello]
command=bash -c "echo waiting 5 seconds . . . && sleep 5"
autorestart=false
numprocs=1
startsecs=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

[program:world]
command=bash -c "echo waiting 10 seconds . . . && sleep 10"
autorestart=false
numprocs=1
startsecs=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

[eventlistener:processes]
command=bash -c "printf 'READY\n' && while read line; do kill -SIGQUIT $PPID; done < /dev/stdin"
events=PROCESS_STATE_STOPPED,PROCESS_STATE_EXITED,PROCESS_STATE_FATAL

【讨论】:

  • 超级答案。效果很好!