Ambari Agent 源碼分析


一、ambari-agent 啟動方式

Ambari-Agent的啟動腳本為/etc/init.d/ambari-agent。該腳本主要實現了start,stop,status,restart,reset方法。對於start,stop,status,reset方法的實現,直接調用/usr/sbin/ambari-agent腳本,將所有命令參數傳入進去,reset直接調用stop,在調用start。 

二、ambari-agent啟動腳本

/usr/sbin/ambari-agent 通過軟鏈接指向/etc/init.d/ambari-agent,其執行過程如下:

1. set -u 腳本執行過程中,如果使用到未定義的變量,則顯示錯誤信息。

set -u # fail on unset variables

2. 參數檢測,如果設置了“–home”參數,則根據參數值,設置HOME_DIR。Ambari-Agent允許在單台節點上運行多個agent客戶端(進行集群模擬),每個客戶端有自己的配置文件目錄。默認情況下,HOME_DIR為空。

export HOME_DIR=""
if [ "$#" = 3 ] && [ $2 = "--home" ] ; then
  export HOME_DIR=$3
  echo "Allow running multiple agents on this host; will use custom Home Dir: $HOME_DIR"
fi

3. 設置環境變量CONFIG_FILE="$HOME_DIR/etc/ambari-agent/conf/ambari-agent.ini",默認情況下,CONFIG_FILE=/etc/ambari-agent/conf/ambari-agent.ini。

export CONFIG_FILE="$HOME_DIR/etc/ambari-agent/conf/ambari-agent.ini"

 4. 解析CONFIG_FILE文件,根據該配置文件,進行相關環境變量的設置。

get_agent_property() {
  property_name="$1"
  value=$(awk -F "=" "/^$property_name/ {print \$2}" $CONFIG_FILE)
  echo $value
}
export PATH=/usr/sbin:/sbin:/usr/lib/ambari-server/*:$PATH
export AMBARI_CONF_DIR=$HOME_DIR/etc/ambari-server/conf:$PATH

# Because Ambari rpm unpacks modules here on all systems
export PYTHONPATH=/usr/lib/ambari-agent/lib:${PYTHONPATH:-}

export AMBARI_PID_DIR=`get_agent_property piddir`
export AMBARI_PID_DIR=`valid_path "${AMBARI_PID_DIR:?}"`
export AMBARI_PID_DIR="${AMBARI_PID_DIR:?}"
export AMBARI_AGENT_LOG_DIR=`get_agent_property logdir`
export AMBARI_AGENT_LOG_DIR=`valid_path "${AMBARI_AGENT_LOG_DIR:?}"`
export AMBARI_AGENT_LOG_DIR="${AMBARI_AGENT_LOG_DIR:?}"
KEYSDIR=`get_agent_property keysdir`
KEYSDIR=`valid_path "${KEYSDIR:?}"`
KEYSDIR="${KEYSDIR:?}"

AMBARI_AGENT=ambari-agent
PYTHON_WRAP=/usr/bin/ambari-python-wrap
PIDFILE=$AMBARI_PID_DIR/$AMBARI_AGENT.pid
OUTFILE=$AMBARI_AGENT_LOG_DIR/ambari-agent.out
LOGFILE=$AMBARI_AGENT_LOG_DIR/ambari-agent.log
AGENT_SCRIPT=/usr/lib/ambari-agent/lib/ambari_agent/main.py
AGENT_TMP_DIR=/var/lib/ambari-agent/tmp
AGENT_WORKING_DIR=/var/lib/ambari-agent
AMBARI_AGENT_PY_SCRIPT=/usr/lib/ambari-agent/lib/ambari_agent/AmbariAgent.py
COMMON_DIR=/usr/lib/ambari-agent/lib/ambari_commons
COMMON_DIR_AGENT=/usr/lib/ambari-agent/lib/ambari_commons
OK=0
NOTOK=1

5. 獲取當前用戶和用戶組。

current_user=`id -u -n`
current_group=`id -g -n`

6. 檢測用戶權限,如果該用戶不是root用戶,則檢查該用戶是否有sudo權限(通過是否能執行sudo -l 命令,只有擁有sudo權限的用戶能使用-l參數)。

if [ "$EUID" -ne 0 ] ; then
  echo "" | sudo -S -l > /dev/null 2>&1
  if [ "$?" != "0" ] ; then
    echo "You can't perform this operation as non-sudoer user. Please, re-login or configure sudo access for this user."
    exit 0
  fi
fi

7. 切換到ambari-agent工作目錄。

cd $AGENT_WORKING_DIR

 8. 配置PYTHON環境變量。

if [ -z "${PYTHON:-}" ] ; then
  export PYTHON=`readlink $PYTHON_WRAP`
fi

9. 從環境變量中讀取 AMBARI_PASSPHRASE,如果存在,則把值賦給 RESOLVED_AMBARI_PASSPHRASE。

if [ ! -z ${AMBARI_PASSPHRASE:-} ]; then
  RESOLVED_AMBARI_PASSPHRASE=$AMBARI_PASSPHRASE
fi

 10. 如果ambari-env.sh 文件存在,執行sudo chown命令修改其擁有者為當前用戶。

# Reading the environment file
if [ -a /var/lib/ambari-agent/ambari-env.sh ]; then
  /var/lib/ambari-agent/ambari-sudo.sh chown -R $current_user "/var/lib/ambari-agent/ambari-env.sh"
  . /var/lib/ambari-agent/ambari-env.sh
fi

11. 如果 AMBARI_AGENT_LOG_DIR 存在,則設定LOGFILE文件名。

if [ ! -z $AMBARI_AGENT_LOG_DIR ]; then
  LOGFILE=$AMBARI_AGENT_LOG_DIR/ambari-agent.log
fi

 12. 如果 AMBARI_AGENT_OUT_DIR 存在,則設定OUTPUT文件名。

if [ ! -z ${AMBARI_AGENT_OUT_DIR:-} ]; then
  OUTFILE=$AMBARI_AGENT_OUT_DIR/ambari-agent.out
fi

13. 設定 AMBARI_PASSPHRASE 環境變量。

if [ -z ${RESOLVED_AMBARI_PASSPHRASE:-} ] &&  [ ! -z ${AMBARI_PASSPHRASE:-} ]; then
  RESOLVED_AMBARI_PASSPHRASE=${AMBARI_PASSPHRASE:-}
  # If the passphrase is not defined yet, use the value from the env file
elif [ -z ${RESOLVED_AMBARI_PASSPHRASE:-} ]; then
  # Passphrase is not defined anywhere, set the default value
  RESOLVED_AMBARI_PASSPHRASE="DEV"
fi

export AMBARI_PASSPHRASE=$RESOLVED_AMBARI_PASSPHRASE

14. 根據參數中傳遞的命令(start、status、stop、restart、reset)執行相應的命令,這里只對start命令進行說明,步驟如下:

  (a) 檢查python版本;

  (b) 根據pid文件,檢查當前是否有正常運行的agent進程(如果存在pid文件,且存在進程的進程號等於pid文件中記錄的進程號,則認為agent已經啟動,則拋出異常,返回) 

  (c) 修改相關文件目錄權限,指定其擁有者為當前用戶;

  (d) 比較 COMMON_DIR 和  COMMON_DIR_AGENT,如果不相同,則返回;

  (e) 執行 python 腳本,啟動 ambari-agent 進程,腳本路徑為:AMBARI_AGENT_PY_SCRIPT=/usr/lib/ambari-agent/lib/ambari_agent/AmbariAgent.py;

  (f) 等待2秒,等待AmbariAgent運行一段時間(AmbariAgent會啟動子進程,該進程會創建pid文件,將子進程的pid號寫入到pid文件中); 

  (g) 根據pid號檢查agent是否啟動正常;

注意:pid文件不是在啟動腳本中創建寫入的,而是在/usr/lib/python2.6/site-packages/ambari-agent/main.py中的daemonize函數中創建寫入的,寫入的是運行main.py的進程號。

三、ambari-agent 啟動過程

    從Ambari-agent啟動腳本可知,ambari-agent啟動入口點為:/usr/lib/python2.6/site-packages/ambari-agent/AmbariAgent.py。下面主要分析AmbariAgent.py的運行過程。 
 AmbariAgent.py腳本比較簡單,主要工作是啟動子進程,運行/usr/lib/python2.6/site-packages/ambari-agent/main.py腳本。當腳本運行結束后,清理其產生的pid文件。 
下面看看main.py主要運行過程。

1. Signal信號綁定: 

  (a) 主要綁定SigInt信號處理器、SigTerm信號處理器 
  (b) 綁定debug類型的SigUSR1,SigUSR2信號和信號處理器   
  (c) 創建HeartBeatSopCallback回調處理器。

2. 執行main 方法:

    (a) 解析運行參數;

  (b) 配置日志處理;

  (c) 加載配置文件,解析配置屬性;

  (d) 如果為 stop 或者 reset 命令,則執行對應的方法;

  (e) 添加系統日志處理器;

     (f)  啟動DataCleaner 線程(如果配置文件中有 data_cleanup_interval 屬性,且其值大於0)

  (g) 執行 ambari-agent 配置檢查;

  (h) 啟動 PingPortListener 線程(該服務器作為一個機器級的全局的鎖);

  (i)  非windows系統,則創建pid文件,寫pid ;

  (j) 獲取配置文件中配置的server列表,依次不斷的去連接server,直到和某個server建立連接(或是agent停止)。如果連接成功,調用 run_threads 方法開始 Server <--> Agent通信流程。

  run_thread方法執行過程如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM