2014-01-20 6 views
2

HAProxy를 실행중인 2 개의 Amazon Linux EC2 인스턴스가 있습니다. 다른 인스턴스에서 각 인스턴스를 모니터링하고 인스턴스를 사용할 수 없게 된 경우 다른 인스턴스는 탄성 IP를 활성 서버로 이동하는 API 명령을 실행합니다.루핑 Bash 스크립트를 서비스로 실행하는 방법은 무엇입니까?

매 20 초마다 모니터링 할 Bash 스크립트를 만들었습니다. 서비스로 실행되도록 스크립트를 설정해야하므로 서비스 래퍼를 만들고 서비스로 발견하여 등록한 템플릿을 기반으로 /etc/init.d에 배치해야합니다.

문제점은 "hamonitor 시작 중 ..."이라는 명령을 #service hamonitor start 명령으로 실행했지만 OK 메시지가 표시되지 않고 중지 명령을 실행해도 실패하고 상태 명령을 실행하면 , 그것은 달리고 있지 않다는 것을 말한다. 그러나 로그를 확인하면 실제로 스크립트가 실행 중임을 보여줍니다. 적절한 PID 파일이 필요하거나 스크립트가 무한 루프에서 실행되기 때문에 OK가 실행되지 않아 완료되지 않는다고 가정합니다.

서비스 래퍼 :

#!/bin/sh 
# 
# /etc/init.d/hamonitor 
# Subsystem file for "hamonitor" server 
# 
# chkconfig: 2345 95 05 (1) 
# description: hamonitor server daemon 
# 
# processname: hamonitor 

### BEGIN INIT INFO 
# Provides: 
# Required-Start: 
# Required-Stop: 
# Should-Start: 
# Should-Stop: 
# Default-Start: 
# Default-Stop: 
# Short-Description: 
# Description:  
### END INIT INFO 

# source function library 
. /etc/rc.d/init.d/functions 

PROG=hamonitor 
EXEC=/etc/haproxy/hamonitor 
LOCKFILE=/var/lock/subsys/$prog 
PIDFILE=/var/run/$prog.pid 
RETVAL=0 

start() { 
    echo -n $"Starting $PROG:" 
    echo 
    #daemon $EXEC & 
    /etc/haproxy/hamonitor & 
    RETVAL=$? 
    if [ $RETVAL -eq 0 ]; then 
     touch LOCKFILE 
     touch PIDFILE 
     echo "[ OK ]" 
    else 
     echo "[ FAIL: ${retval} ]" 
    fi 
    return $RETVAL 
} 

stop() { 
    echo -n $"Stopping $PROG:" 
    echo 
    killproc $PROG -TERM 
    RETVAL=$? 
    if [ $RETVAL -eq 0 ]; then 
     rm -f LOCKFILE 
     rm -f PIDFILE 
     echo "[ OK ]" 
    else 
     echo "[ FAIL: ${RETVAL} ]" 
    fi 
    return $RETVAL 
} 

case "$1" in 
    start) 
    start 
    ;; 
    stop) 
    stop 
    ;; 
    status) 
    status $PROG 
     RETVAL=$? 
    ;; 
    restart) 
    stop 
    start 
    ;; 
    *) 
    echo $"Usage: $0 {start|stop|status|restart}" 
    RETVAL=1 
esac 

exit $RETVAL 

앱 :

#!/usr/bin/env bash 

export EC2_HOME=/opt/aws/apitools/ec2 
export JAVA_HOME=/usr/lib/jvm/jre 

AWS_ACCESS_KEY="XXXXXXXXXXXXXXXXXXXXXXXXX" 
AWS_SECRET_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 
VIP1="1.2.3.4" 
VIP1_ALLOCATIONID="eipalloc-XXXXXXX" 
THIS_NODE_EC2_ID="i-XXXXXXX" 
THIS_NODE_PRIVATE_IPADDRESS1="10.60.0.11" 
THIS_NODE_HEALTHCHECK_URL="http://10.60.0.10/haproxy?monitor" 
OTHER_NODE_HEALTHCHECK_URL="http://10.60.49.50/haproxy?monitor" 
CHECK_OTHER_INTERVAL=5 
CHECK_OTHER_FAIL_COUNT=0 
CHECK_OTHER_RUN_COUNT=0 
AFTER_TAKEOVER_WAIT=30 

function takeover_vips { 
    /opt/aws/bin/ec2-associate-address -aws-access-key ${AWS_ACCESS_KEY} -aws-secret-key ${AWS_SECRET_KEY} -a ${VIP1_ALLOCATIONID} -i ${THIS_NODE_EC2_ID} -private-ip-address ${THIS_NODE_PRIVATE_IPADDRESS1} -allow-reassociation > /dev/null 
} 

function does_this_node_have_ips { 
    is_active=$(/opt/aws/bin/ec2-describe-addresses -aws-access-key ${AWS_ACCESS_KEY} -aws-secret-key ${AWS_SECRET_KEY} | grep ${VIP1} | grep ${THIS_NODE_EC2_ID}) 
    if [ "$is_active" = "" ]; then 
    echo "no" 
    else 
    echo "yes" 
    fi 
} 

function log_msg { 
    msg=$1 
    msg="$(date) -- ${msg}" 
    echo ${msg} >> /var/log/hamonitorlog 
} 

while [ . ]; do 
    healthcheck_response=$(curl -sL -w "%{http_code}" ${OTHER_NODE_HEALTHCHECK_URL} -o /dev/null) 
    if [ "$healthcheck_response" != "200" ]; then 
     CHECK_OTHER_FAIL_COUNT=$((CHECK_OTHER_FAIL_COUNT+1)) 
     if [ "$CHECK_OTHER_FAIL_COUNT" -gt 2 ]; then 
      takeover_vips 
      CHECK_OTHER_FAIL_COUNT=0 
      sleep ${AFTER_TAKEOVER_WAIT} 
     fi 
    sleep ${CHECK_OTHER_INTERVAL} 
done 

답변

3

일부 리눅스 배포판이 up-start 및 기타 init; 나는 당신이 init이라고 가정합니다. chkconfig심볼릭 링크을 유지하는 데 사용됩니다. 귀하는 귀하의 시스템에 맞는 내용의 댓글 (

)을 확인해야합니다.
# chkconfig: 2345 95 05 (1) 

이 해당 시스템에 적합한 것입니다.

짐작할 수 있듯이 daemon이 스크립트를 통해 호출되어야합니다. 어떤 init 스크립트 라이브러리에서는 /etc/rc.d/init.d/functions과 같은 스크립트 함수 일 수 있습니다. 존재하는 경우 daemon() 함수를 사용하는 것이 좋습니다. 하나,

daemon $EXEC &            #option1 
    nohup /etc/haproxy/hamonitor </dev/null> /dev/null 2>&1 & #option2 
    /etc/haproxy/hamonitor&          #option3, 2 lines. 
    disown $!             #... 

이것은 SIGCHLD 및 프로세스의 반환 상태 (이상 man wait 참조)과 관련이있다. 또한 제어 터미널에서 hamonitor을 분리해야 할 수도 있습니다. 이 경우에는 logger을 사용하여 정보를 시스템 로그에 보낼 수 있습니다. 스크립트는 hamonitor 코드입니까? echo에서 logger으로 변경하십시오. hamonitor표준 출력, 표준 입력, 및/또는 표준 에러 필요

경우에, 당신은 그것을 필요로하는 경우 다른 파일로 리디렉션해야합니다. 이 경우 screen을 통해 실행하는 것도 고려해 볼 수 있습니다.

편집 : 마지막 옵션을 사용하여 적절한 PIDFILE을 만들 수 있습니다. 예를 들어,

# !!! optional grabbing of lock here... 
    /etc/haproxy/hamonitor & # spawn in bg 
    HA_PID=$!     # record spawn pid 
    echo $HA_PID > $PIDFILE # record the PID to a file for `stop`. 
    # !!! optional release of lock here... 
    disown $HA_PID    # detach script from terminal. 
echo 등을 사용해서는 안

서비스; logger이 더 좋습니다. hamonitor이 무언가를 읽지 않으면 문제가되지 않을 수 있습니다.주로 문제는 이 disown이 아닌 경우 hamonitor이 완료 될 때까지 기다릴 것이므로 rc 스크립트의 시작이 완료되지 않습니다.

일반적으로, 당신은 보이는 파일에 대한 링크를 제공하거나 배포 및 버전을 제공 (또는 적어도 리눅스 표준베이스 적합성, 는 /etc/rc.d/init.d/functions 볼 수 있습니다 이것이 다른 버전에서 어떻게 작동해야하는지 정의하기 위해). 파일은 각 Linux마다 다를 수 있습니다. 당신은 무엇을 환경 변수, 파일 등이 예상과 어떤 기능이 파일에 사용되는 볼이 당신이 이해하는 경우 파일을 직접 스크립팅 볼 수 있습니다. 예를 들어 killproc이 여기에 정의되어 있습니다. 앱에서 연속 루프를 실행하고 나는 실제로 적절한 PID 파일을 사용하고 있지 않다 때문에

+0

이렇게해야 문제를 일으킬 수 없습니다? – jpshook

+0

'LOCKFILE'과'PIDFILE'은 보통 파일입니다; 특히 */etc/rc.d/init.d/functions *에서 어떤 함수도 사용하지 않으면; 이러한 함수에는 ** API **가있어 이러한 파일을 설정할 수 있습니다. [LFS의 init.d/functions] (http://www.linuxfromscratch.org/lfs/view/6.4/scripts/apds02.html)를 참조하십시오. 'killproc()'는 $ PIDFILE이'start()'에서 무언가를 죽이기를 원합니다. $ PIDFILE은'$! '이어야합니다. 편집을 참조하십시오. 그러나 이것이 당신의 * 시작 *이 실패하는 이유는 아닙니다. –

+0

'killproc()'대신'pkill'이나'killall'을 사용할 수 있습니다. 그런 다음 * PIDFILE *이 필요하지 않습니다. * LOCKFILE *은 일반적으로 여러 동시 시작을 방지합니다. 나는 확실히 중복을 방지 할 –

관련 문제