我的supervisord.conf中的当前部分如下所示:
[程序:的RabbitMQ] 命令= / usr / sbin目录/ RabbitMQ的服务器
当我尝试用supervisord(supervisorctl stop rabbitmq)停止rabbitmq时,rabbitmq进程根本不会关闭。 rabbitmq文档还提到永远不要使用kill,而是使用rabbitmqctl stop。我猜测supervisord只会杀死进程 - 因此使用rabbitmq会导致糟糕的结果。我在supervisord中找不到任何选项来指定自定义停止命令。
你有什么建议吗?
答案 0 :(得分:36)
我的解决方案是编写一个名为rabbitmq.sh的包装脚本,如下所示:
# call "rabbitmqctl stop" when exiting
trap "{ echo Stopping rabbitmq; rabbitmqctl stop; exit 0; }" EXIT
echo Starting rabbitmq
rabbitmq-server
之后,修改supervisord.conf:
[program:rabbitmq]
command=path/to/rabbitmq.sh
答案 1 :(得分:3)
此脚本启动RabbitMQ作为后台进程(使用'&'),这会导致更新/创建pid文件(请参阅http://www.rabbitmq.com/man/rabbitmqctl.1.man.html下的'wait')。
启动兔子后,使用循环验证pid是否仍在运行。如果兔子崩溃或手动关闭(在supervisord之外),那么脚本将以1退出并且supervisord接管。
回声>> ./rmq.txt文件用于调试目的,可以在生产中注释掉(我用它来监视启动/关闭/死亡状态)。
supervisord很高兴,因为它可以看到正在运行的进程,而EXIT将触发stop_rmq函数,该函数调用'rabbitmqctl stop'进行干净关闭。
#!/bin/bash
# Script to manage RMQ with supervisord
# Shut down rmq
function stop_rmq {
echo "Stopping RabbitMQ..."
echo "Stopping RabbitMQ..." >> ./rmq.txt
rabbitmqctl stop
echo "RabbitMQ stopped"
echo "RabbitMQ stopped" >> ./rmq.txt
#exit 0
}
# Set up the trap
#trap stop_rabbit TERM KILL HUP INT SIGTERM SIGKILL SIGHUP SIGINT
trap stop_rmq exit
# Start rmq
echo "Starting RabbitMQ..."
echo "Starting RabbitMQ..." >> ./rmq.txt
# Start Rabbitmq in the background (causes the pid file to be updated)
# Note that the pid file location can be overridden with the rmq 'RABBITMQ_PID_FILE' variable
/usr/sbin/rabbitmq-server &
rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbit@$HOSTNAME.pid
echo "RabbitMQ Started"
echo "RabbitMQ Started" >> ./rmq.txt
while true; do
#ps $(cat /var/lib/rabbitmq/mnesia/rabbit@$HOSTNAME.pid)
ps -o pid,cmd,etime $(cat /var/lib/rabbitmq/mnesia/rabbit@$HOSTNAME.pid)
if (($? > 0)); then
echo "RabbitMQ Died"
echo "RabbitMQ Died" >> ./rmq.txt
exit 1
fi
#echo "Sleeping..."
sleep 10
done
这是脚本向supervisord生成的输出:
foo@bar:/# supervisorctl tail rmq
Starting RabbitMQ...
Waiting for rabbit@a2d2c8f9cad2 ...
pid is 45220 ...
RabbitMQ 3.3.5. Copyright (C) 2007-2014 GoPivotal, Inc.
## ## Licensed under the MPL. See http://www.rabbitmq.com/
## ##
########## Logs: /var/log/rabbitmq/rabbit@a2d2c8f9cad2.log
###### ## /var/log/rabbitmq/rabbit@a2d2c8f9cad2-sasl.log
##########
Starting broker... completed with 0 plugins.
...done.
RabbitMQ Started
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:05
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:15
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:25
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:35
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:45
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 00:55
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 01:05
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 01:15
PID CMD ELAPSED
45220 /usr/lib/erlang/erts-6.1/bi 01:25
答案 2 :(得分:2)
您已回答了自己的问题。在正常操作中,永远不要在任何进程上使用kill,除非这是记录的正常管理方式。在RabbitMQ的情况下,记录的过程是使用rabbitmqctl stop或使用rabbitmqserver stop。
管理RabbitMQ没有充分理由比使用rabbitmqserver start重启的shell脚本更复杂。如果这不能立即起作用,那么RabbitMQ由于诸如缺少RAM,磁盘空间不足或者流氓系统管理工具删除了一些rabbitmq二进制组件而导致严重损坏。
在正常操作中,RabbitMQ有一个内部管理程序,它将尝试关闭并重新启动RabbitMQ,因此如果删除二进制文件,它将无法重新启动。使用chef,puppet,cfengine等工具时,请勿反复推出二进制包文件。只要检查一切都在那里。
答案 3 :(得分:1)
我建议你使用Monit(http://mmonit.com/),它更适合像RabbitMQ这样的守护进程,而且功能也很丰富。
首先,您必须安装Monit软件包。如果您在Ubuntu / Debian下:
sudo apt-get update
sudo apt-get install monit
之后,您必须创建配置脚本。 这是一个让您运行的示例脚本(将其放在/etc/monit/conf.d /上):
set daemon 1800
set logfile /var/log/monit.log
check process rabbit with pidfile /var/run/rabbitmq/pid
start program = "/etc/init.d/rabbitmq-server start"
stop program = "/etc/init.d/rabbitmq-server stop"
noalert foo@bar
然后,只需重启monit即可完成:
sudo /etc/init.d/monit restart