25

我的 supervisord.conf 中的当前部分如下所示:

[程序:rabbitmq] 命令=/usr/sbin/rabbitmq-server

当我尝试使用 supervisord ( supervisorctl stop rabbitmq) 停止 rabbitmq 时,rabbitmq 进程根本不会关闭。rabbitmq 文档还提到不要使用 kill 而是使用 rabbitmqctl stop 。我猜supervisord只是简单地杀死了进程——因此rabbitmq的结果很差。我在 supervisord 中找不到任何选项来指定自定义停止命令。

你有什么建议?

4

4 回答 4

38

我的解决方案是编写一个名为 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 
于 2012-03-21T11:45:24.080 回答
3

你已经回答了你自己的问题。在正常操作中,切勿在任何进程上使用 kill ,除非这是记录在案的正常管理方式。在 RabbitMQ 的情况下,记录的过程是使用 rabbitmqctl stop 或使用 rabbitmqserver stop。

没有充分的理由使用比尝试通过 rabbitmqserver start 重新启动的 shell 脚本更复杂的东西来管理 RabbitMQ。如果这不能立即起作用,那么 RabbitMQ 就会因为诸如 RAM 不足、磁盘空间不足或流氓系统管理工具删除了一些 rabbitmq 二进制组件等原因而严重崩溃。

在正常操作中,RabbitMQ 有一个内部主管会尝试关闭并重新启动 RabbitMQ,因此如果您删除二进制文件,它将无法重新启动。使用 chef、puppet、cfengine 等工具时,不要重复推出二进制包文件。只需检查所有内容是否应有。

于 2012-01-29T06:53:05.937 回答
3

此脚本将 RabbitMQ 作为后台进程启动(使用“&”),这会导致更新/创建 pid 文件(参见http://www.rabbitmq.com/man/rabbitmqctl.1.man.html下的“等待” ) .

rabbit 启动后,会使用一个循环来验证 pid 是否仍在运行。如果 rabbit 崩溃或被手动关闭(在 supervisord 之外),那么脚本将以 1 退出并由 supervisord 接管。

echo >> ./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
于 2014-08-22T14:39:27.400 回答
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
于 2013-06-03T14:09:47.437 回答