Как правильно управлять rabbitmq с помощью supervisord

#rabbitmq #supervisord

#rabbitmq #supervisord

Вопрос:

Текущий раздел в моем supervisord.conf выглядит так:

[program:rabbitmq] command=/usr/sbin/rabbitmq-server

Когда я пытаюсь остановить rabbitmq с помощью supervisord ( supervisorctl stop rabbitmq), процессы rabbitmq просто не завершаются. В документации rabbitmq также упоминается, что никогда не следует использовать kill, а использовать rabbitmqctl stop . Я предполагаю, что supervisord просто убивает процессы — отсюда и плохие результаты с rabbitmq. Я не смог найти в supervisord никаких опций для указания пользовательской команды остановки.

У вас есть какие-либо рекомендации?

Ответ №1:

Мое решение — написать сценарий-оболочку с именем 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. Это частично сработало для меня. Я создал суть своего окончательного решения: gist.github.com/caioariede/342a583f75467509ad42

2. @caio хотя мое решение работает для меня, я должен поблагодарить вас за ваше.

Ответ №2:

Вы ответили на свой собственный вопрос. При нормальной работе никогда не используйте kill для какого-либо процесса, если только это не документированный обычный способ управления им. В случае RabbitMQ документированный процесс заключается в использовании rabbitmqctl stop или использовании rabbitmqserver stop.

Нет веской причины управлять RabbitMQ с помощью чего-либо более сложного, чем сценарий оболочки, который делает одну попытку перезапуска через запуск сервера rabbitmq. Если это не сработает сразу, значит, RabbitMQ не работает из-за чего-то вроде нехватки оперативной памяти, нехватки места на диске или того, что мошеннический инструмент управления системой удалил некоторые двоичные компоненты rabbitmq.

При нормальной работе RabbitMQ имеет внутренний супервизор, который попытается завершить работу и перезапустить RabbitMQ, поэтому, если вы удалите двоичные файлы, перезапуск не удастся. При использовании таких инструментов, как chef, puppet, cfengine, не следует повторно извлекать двоичные файлы пакетов. Просто убедитесь, что все на месте, как и должно быть.

Ответ №3:

Этот скрипт запускает RabbitMQ как фоновый процесс (используя ‘amp;’), который приводит к обновлению / созданию файла pid (см. «Ожидание» вhttp://www.rabbitmq.com/man/rabbitmqctl.1.man.html).

После запуска rabbit используется цикл для проверки того, что pid все еще выполняется. Если rabbit выходит из строя или отключается вручную (за пределами supervisord), сценарий завершится с 1, и supervisord вступит во владение.

Эхо >> ./rmq.txt файл существует для целей отладки и может быть закомментирован в процессе производства (я использовал это для отслеживания статуса запуска / выключения / смерти).

supervisord доволен, потому что он может видеть запущенный процесс, и выход вызовет функцию 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 amp;
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
  

Ответ №4:

Я бы посоветовал вам использовать 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
  

Комментарии:

1. он не создает какой-либо файл pid в каталоге /var/run/rabbitmq/.

2. это не причина для отклонения голоса комментатора. на самом деле, monit мог бы быть совершенно правильным решением, если бы не этот файл pid (который можно установить с помощью переменной среды …)