supervisor之啓動rabbitmq報錯緣由

前言

今天重啓了服務器,發現supervisor管理的rabbitmq的進程竟然啓動失敗了,查看日誌發現總是報錯,記錄一下解決的辦法。linux

報錯:erlexec:HOME must be set

  • 找了網上的許多人的博客,通常的說法是在進程的啓動的腳本中加入:
export HOME=/usr/local/erlang
export PATH=$PATH:$HOME/bin
  • 系統默認的HONE是/root,可能形成erlang語言環境獲取不到HOME參數;上述修改能夠用在chkconfig管理和service管理的進程中,可是對於supervisor管理的進程,因爲進程的啓動命名在supervisor.conf中,不能直接修改HOME參數。

辦法: 在supervisor的啓動腳本中加入上述語句。服務器

vi Ssupervisor.conf

#!/bin/sh
# chkconfig: 2345 70 90

export HOME=/usr/local/erlang
export PATH=$PATH:$HOME/bin
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
  • 這樣作能夠保證只是臨時改變了HOME,可是對系統的HOME沒有影響。

溯源

  • 爲何會有這個錯誤?

這個錯誤不是rabbitmq的緣由,而是erlang語言環境的緣由;查看一個erl進程:函數

ps aux | grep beam

# 結果:
root      1779  0.4  0.5 3863876 86060 ?       Sl   19:21   0:06 /usr/local/erlang/bin/x86_64-unknown-linux-gnu/beam.smp -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 32000 -K true -B i -- -root /usr/local/erlang -progname erl -- -home /root
  • 能夠看到-home參數就是啓動是加進去的,啓動一個erl實例,其調用了erlexec的c文件;
# erlexec.c 文件的路徑爲/usr/local/erlang/erts/etc/common/erlexec.c

# 部分代碼
static char * home;
static char ** Eargsp = NULL;
static int EargsCnt = 0;
static char **argsp = NULL;

static void get_home( void )
{
    home = get_env("HOME");
    if (home == NULL)
        error("HOME must be set");
}
  • 能夠看到get_env函數獲取HOME環境變量,若是獲取失敗就輸出‘HOME must be set’。rest

  • 目前一個不明白的地方是HOME參數有一個默認的值/root,爲何get_env函數獲取不到,而是返回了null;有待繼續研究;日誌

rabbitmq重啓失敗

  • 發現手動殺死rabbitmq的進程後,supervisor重啓rabbitmq要麼失敗,要麼不重啓;code

  • 若是採起supervisor後臺的進程管理來啓動和中止rabbitmq是能夠的,可是若是手動殺死rabbitmq進程則沒法重啓進程;server

緣由:rabbitmq

  1. rabbitmq使用rabbitmq-server start 或使用rabbitmq-server啓動後,會有兩個進程,一個是erlang的節點服務程序;一個是rabbitmq的應用程序;rabbitmq的應用程序在erlang的節點上運行;進程

  2. 若是強制殺死rabbitmq的應用程序進程,supervisor會嘗試啓動,這時會嘗試啓動erlang的節點服務程序和rabbitmq的應用程序,發現已經存在一個erlang的節點服務程序,因此啓動會失敗;get

  3. 若是強制殺死erlang的節點服務程序,這時erlang的節點服務程序和rabbitmq的應用程序都會被中止,若是配置參數爲autorestart=unexpected 的話,那麼supervisor不會去重啓該進程,若是參數設置爲autorestart=true,那麼supervisor會去重啓erlang的節點服務程序和rabbitmq的應用程序;

結論:

  1. 由supervisor管理rabbitmq進程並非很合適,由於在rabbitmq的應用程序崩潰而erlang的節點服務程序正常的狀況下,重啓是失敗的;

  2. 若是隻有節點在運行,可是沒有rabbitmq的應用程序實例,那麼對於rabbitmq的管理後臺也是沒法登錄的。

相關文章
相關標籤/搜索