Процесс запуска RabbitMQ на Linux

    Вступление

    Запуск RabbitMQ сервера при более глубоком рассмотрении выглядит весьма запутанным делом. Почему это так и как все все обстоит на самом деле можно прочитать под катом.
    1. Версия RabbitMQ-Server — 2.1.0
    2. ОС: Fedora

    Коротко

    Внимательно смотрим на PID'ы процессов. Ниже идет объяснение происходящего:
    -bash-3.2# /etc/init.d/rabbitmq-server start
    root  7732  3834  0 11:54 pts/0    00:00:00 /bin/sh /etc/init.d/rabbitmq-server start
    root      7733  7732  0 11:54 pts/0    00:00:00 /bin/sh /usr/sbin/rabbitmq-multi start_all 1
    root      7740  7733  0 11:54 pts/0    00:00:00 su rabbitmq -s /bin/sh -c /usr/lib/rabbitmq/bin/rabbitmq-multi  "start_all" "1"
    rabbitmq  7741  7740  7 11:54 ?        00:00:00 /usr/lib64/erlang/erts-5.7.5/bin/beam.smp -- -root /usr/lib64/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr/lib/rabbitmq/lib/rabbitmq_server-  2.1.0/sbin/../ebin -noshell -noinput -hidden -K true -sname rabbitmq_multi7741 -s rabbit_multi -extra start_all 1
    rabbitmq  7767  7741  0 11:54 ?        00:00:00 inet_gethost 4
    rabbitmq  7768  7767  0 11:54 ?        00:00:00 inet_gethost 4
    rabbitmq  7769  7741  0 11:54 ?        00:00:00 /bin/sh /usr/lib/rabbitmq/bin/rabbitmq-server -noinput
    rabbitmq  7794  7769  0 11:54 ?        00:00:00 /bin/sh /usr/lib/rabbitmq/bin/rabbitmq-server -noinput
    rabbitmq  7795  7794  0 11:54 ?        00:00:00 ps -ef
    rabbitmq  7796  7794  0 11:54 ?        00:00:00 grep rabbit
    -bash-3.2# echo $$
    3834

    Подробнее

    • Из shell (PID = 3834) запускается /etc/init.d/rabbitmq-server start;
    • В init.d скрипте (PID = 7732) происходит подгрузка (source) конф. файла /etc/sysconfig/rabbitmq;
    • Из init.d скрипта запускается shell скрипт su rabbitmq -s /bin/sh -c /usr/lib/rabbitmq/bin/rabbitmq-multi «start_all» «1» (PID = 7740); Из него подгужается (source) /usr/lib/rabbitmq/bin/rabbitmq-evn, в котором подгужается /etc/rabbimq/rabbitmq.conf
    • В /usr/lib/rabbitmq/bin/rabbitmq-multi запускается erlang (PID = 7741) с некоторым набором параметром. Наиболее интересным является -s rabbit_multi. Указывающий функцию, которая будет вызвана вместо start (man erl);
    • Из запущенного erlang приложения запускается shell скрипт /bin/sh /usr/lib/rabbitmq/bin/rabbitmq-server -noinput (PID = 7769), в котором и происходит запуск самого rabbitmq-server.
    Вот код из rabbit_mulri.erl, в котором происходит вызов shell скрипта:
     220 run_rabbitmq_server() ->
     221     with_os([{unix, fun run_rabbitmq_server_unix/0},
     222              {win32, fun run_rabbitmq_server_win32/0}]).
     223
     224 run_rabbitmq_server_unix() ->
     225     CmdLine = getenv("RABBITMQ_SCRIPT_HOME") ++ "/rabbitmq-server -noinput",
     226     erlang:open_port({spawn, CmdLine}, [nouse_stdio]).
     227 
     228 run_rabbitmq_server_win32() ->
     229     Cmd = filename:nativename(os:find_executable("cmd")),
     230     CmdLine = "\"" ++ getenv("RABBITMQ_SCRIPT_HOME")
     231                                          ++ "\\rabbitmq-server.bat\" -noinput",
     232     erlang:open_port({spawn_executable, Cmd},
     233                      [{arg0, Cmd}, {args, ["/q", "/s", "/c", CmdLine]},
     234                       nouse_stdio, hide]).
    
    Настолько нетривиальный процесс запуска явно делается из-за мультиплатформенности самого приложения.
    Переменные окружения
    Теперь у нас есть понимание того, как происходит процесс запуска rabbitmq-server, но нет понимая того как на него повлиять. Рассмотрим немного подробнее запуск самих erlang приложений.
    Запуск лаунчера (rabbit_multi)
     exec erl \
       -pa "${RABBITMQ_HOME}/ebin" \
       -noinput \
       -hidden \
       ${RABBITMQ_MULTI_ERL_ARGS} \
       -sname rabbitmq_multi$$ \
       -s rabbit_multi \
       ${RABBITMQ_MULTI_START_ARGS} \
       -extra "$@"
    
    Запуск сервера
    exec erl
    ${RABBITMQ_EBIN_PATH}
       ${RABBITMQ_START_RABBIT}
       -sname ${RABBITMQ_NODENAME}
       -boot ${RABBITMQ_BOOT_FILE}
       ${RABBITMQ_CONFIG_ARG}
       +W w \
       ${RABBITMQ_SERVER_ERL_ARGS} \
       ${RABBITMQ_LISTEN_ARG} \
       -sasl errlog_type error \
       -kernel error_logger '{file,"'${RABBITMQ_LOGS}'"}' \
       -sasl sasl_error_logger '{file,"'${RABBITMQ_SASL_LOGS}'"}' \
       -os_mon start_cpu_sup true \
       -os_mon start_disksup false \
       -os_mon start_memsup false \
       -mnesia dir "\"${RABBITMQ_MNESIA_DIR}\"" \
       ${RABBITMQ_SERVER_START_ARGS} \
       "$@"
    
    Думаю теперь видно какие переменные окружения влияют на каждый из erlang процессов. Изменять данные параметры рекомендуется в /etc/rabbitmq/rabbitmq.conf, который как мы помним подгружается при запуске /usr/lib/rabbitmq/bin/rabbitmq-multi.Вот так выглядит запущенный сервис с параметрами по-умолчанию:
    
    exec erl -noinput -sname rabbit@hostname -boot /var/lib/rabbitmq/mnesia/rabbit@hostname/plugins-scratch/rabbit \    
       -config /etc/rabbitmq/rabbitmq +W w  +K true +A30 +P 1048576 -kernel inet_default_listen_options [{nodelay,true}] \
       -kernel inet_default_connect_options [{nodelay,true}] \
       -sasl errlog_type error -kernel error_logger '{file,'/var/log/rabbitmq/rabbit@hostname.log'}' \
       -sasl sasl_error_logger '{file,'/var/log/rabbitmq/rabbit@hostname-sasl.log'}' \
       -os_mon start_cpu_sup true -os_mon start_disksup false -os_mon start_memsup false -mnesia dir "/var/lib/rabbitmq/mnesia/rabbit@hostname" -noinput
    

    Итог по конф. файлам

    В итоге за работу rabbitmq-server отвечают 3 конф. файла:
    • /etc/sysconfig/rabbitmq; — В нем принято указывать какие-либо низкоуровневые параметры (например ulimit)
    • /etc/rabbitmq/rabbitmq.conf; — Настраиваются переменные окружения для запуска erlang
    • /etc/rabbitmq/rabbitmq.config. — Настраивается сам rabbitmq-server
    Надеюсь кому-то эта статья сэкономит немного времени. О том какие именно значения выставлять переменным, влияющим на работу сервера — это уже дело личное. Возможно я напишу об этом несколько позже.

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

      +3
      добавьте в шапку статьи коротенькое описание, что же это за зверь такой, RabbitMQ.
        –3
        не вижу смысла писать о том, что может быть найдено менее чем за минуту.
          0
          из уважения к аудитории.
            +2
            из остатков уважения к аудитории он таки не добавил
            похвально
        +1
        Спасибо за подробное исследование.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое