출처 : http://egloos.zum.com/pelican7/v/843738

Shell script를 이용한 무정지 서버 만들기


서버 프로그램을 만들다 보니 이넘이 가끔 죽을때가 있다.

최대한 죽지않게 만들기는 하지만 장담할 수는 없는 노릇이다.

그래서 여러가지 방법을 강구해봤다.

Runtim 객체를 이용한 무정지 서버도 만들어 보았지만 이것 또한 문제가 발생했다.

A 라는 서버 프로그램을 체크하기 위해 B 라는 프로그램을(이것도 서버 프로그램이다.) 만들어서 체크를 한다고 할때 무난히 잘 작동 되기는 한다. 하지만 B가 죽으면 어찌될까.

결국 원점이 된다.

많은 방법중에 그래도 Shell Script 를 이용한 방법이 가장 간단하고 그 활용 범위뿐 아니라 작성 방법도 훨씬 간단하다.

이 방법또한 리눅스를 기반으로 설명한다.

Windows 계열에서는 사용할 수 없다는게 좀 많이 아쉽기는 하다. (실은 내가 윈도우쪽 스크립트를 모른다.ㅡㅡ;; 배우고픈데 설명나온데두 엄따..ㅠㅠ)



어찌됬든 리눅스에서 함 해보자. 무지 간단하니..^^

아.. 먼저 쉘스크립트를 하나두 모르는 사람은 좀이라두 공부해 두기 바란다.

아래 사이트에 방대한 양의 설명이 있다. 존경을 표한다..ㅡㅡ;;

http://kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/index.html



모 모르더라두 내용이 간단하니 금방 이해하리라 본다.

이제 시작하도록 하겠다.



무정지 서버를 만들기 위해서는 주기적인 프로세스의 체크가 필수다. 물론 다 알거라 생각한다.

그래서 쉘 스크립트에서 가장 중요한 루프문에 대해 알아보자.

루프문은여러가지가 있지만 그 루프문은 각자 공부해 보기 바라며 내가 주로 사용하는 루프문(while)에 대해서만 얘기 하도록 하겠다.



while [condition]
do 
command... 
done 



위 처럼 사용하면 된다.

조건(condition) 부분은 해당 조건을 넣으면 된다.

우리는 무정지 서버를 만들것이기 때문에 조건에 참이되는 값을 넣으면 된다.

나는 1 을 주로 사용한다.^^

그래서 위 조건을 이용해서 간단히 스트링을 주기적으로(10초) 체크하는 스크립트를 만들려면 어떻게 하면 될까?.. 다들 이해했으리라 본다.

한가지만 생각하면 된다. 

sleep 시간(초단위) <-- 요넘이 필요하다. 잠깐 재워놔야 되니깐..



그래서 해당 스크립트를 작성하면

-------------------------------------------------

#!/bin/bash

while [ 1 ]

do

    echo "무정지 서버"

    sleep 10

done

-------------------------------------------------

하하. 무지하게 쉽다.

이게 무정지 서버 스크립트다. ^^;;



하지만 저렇게만 만들어 놓으면 넘 재미없지 않은가... 그리고 약간 이해가 가지 않는 사람을 위해서 몇가지 더 추가해보기로 하자.



우리가 필요한거 주기적인 프로세스 체크 스크립트가 필요하다.

프로세스체크 명령어는 아래와 같으며 명령 실행 결과는 해당 프로세스의 프로세스아이디(PID) 값을 획득하는 명령어이다.
명령어는 다양한 방법으로 사용 가능하므로 꼭 아래처럼 사용해야만 하는것은 아니다.

ps -ex|grep "프로세스명"|grep -v grep|awk '{print $1}'



--> grep -v grep : grep 로 실행된 프로세스 명령을 제외한다.

--> awk '{print $1}' : 출력된 결과의 첫번째 필드만을 획득한다.



자 이렇게해서 우리는 해당 프로세스를 체크할 수 있게되었다.

스크립트를 조금 수정해보면 좀더 깔끔한 모습이 될것이다.(프로그램명을 TestServer 이라하자)



-------------------------------------------------

#!/bin/sh

# 띄어쓰기에 주의해라.

while [ 1 ] 
do
  PC=`ps -ex|grep TestServer|grep -v grep | awk '{print $1}'`
  if [ "$PC" == "" ]             # 실행 프로세스가 없으면
  then
    CMD=`./TestServer &`   # 실행 경로에 주의해라
  fi
  sleep 10
done

-------------------------------------------------

또는

-------------------------------------------------

#!/bin/sh

# 띄어쓰기에 주의해라.

while [ 1 ] 
do
  CNT=`ps -ex|grep TestServer|grep -v grep | wc -l`
  if [ $CNT > 0 ]                # 실행 프로세스가 없으면
  then
    CMD=`./TestServer &`   # 실행 경로에 주의해라
  fi
  sleep 10
done

-------------------------------------------------

위처럼 주기적으로 해당 프로세스를 체크하는 쉘 스크립트를 작성하면 무정지 서버를 위한 쉘스크립트가 거의 다 모습을 갖추었다고 할 수 있다.


나머지는 스스로 좀더 깔끔하고 아름다운 스크립트를 만들어 보기 바란다..

어쩌면 여기서 부터가 더 재미 있을 수 있따..^___^

아래에 내가 주로 사용하는 스크립트에 대해서 기술하였다.

하지만 별도 설명은 하지 않겠다. 쉘을 공부하면서 하다보면 무한한 창작(?)력이 생길것이다.

먼저 아래 스크립트는 다음과 같은 조건하에서 실행되게 작성한 쉘이다.

이렇게 작성하면 훨씬 깔끔하다(나만의 생각일 수도..ㅡㅡ;;)

1. 프로그램 이름은 TestServer 로 명명된 Java 프로그램이다.

2. 해당 프로그램을 실행/중지 시키는 별도 쉘을 따로 작성하고 실행시 그 쉘을 실행한다.

시작/종료 쉘 스크립트는 아래처럼 작성한다.

<시작 쉘> - startServer.sh
--------------------------------------------------------------------
#!/bin/sh

Log=/home/test/test.out
DATE=`date +%Y%m%d-%H%M%S`

mv -f "$Log" "$Log_`date +%Y-%m-%d-%H%M`"

echo "#################################################" >> $Log
echo "  Test 서버를 시작합니다.."

Cnt=`ps -ex|grep "TestServer"|grep -v grep|wc -l`
PROCESS=`ps -ex|grep "Test"|grep -v grep|awk '{print $1}'`

if [ $Cnt -ne 0 ]
then
   echo "$DATE : Test 서버(PID : $PROCESS)가 이미 동작하고 있습니다." >> $Log
else
   nohup java TestServer >> $Log &
   echo "$DATE : Test 서버가 시작되었습니다." >> $Log
fi

echo "#################################################" >> $Log
--------------------------------------------------------------------

<종료 쉘> - stopServer.sh
--------------------------------------------------------------------
#!/bin/sh

Log=/home/test/test.out
DATE=`date +%Y%m%d-%H%M%S`

echo "#################################################" >> $Log
echo "  Test 서버를 종료합니다.."

Cnt=`ps -ex|grep "Test"|grep -v grep|wc -l`
PROCESS=`ps -ex|grep "Test"|grep -v grep|awk '{print $1}'`

if [ $Cnt -ne 0 ]
then
   kill -9 $PROCESS
   echo "$DATE : Test 서버(PID : $PROCESS)가 중지되었습니다." >> $Log
else
   echo "$DATE : Test 서버가 실행중이 아닙니다." >> $Log
fi

echo "#########################################" >> $Log
--------------------------------------------------------------------



<무정지 서버 시작 쉘 스크립트> - startMonitor.sh
----------------------------------------------------------------------------------
#!/bin/bash

Log=/home/test/monitor.out
DATE=`date +%Y%m%d-%H%M%S`
NORMAL_SLEEP=60     #정상시 대기 시간
PROB_SLEEP=5     #장애발생시 대기 시간(장애시 곧바로 시작하기 위해)

#Log File Rename
mv -f "$Log" "${Log}_`date +%Y-%m-%d-%H%M`"

echo "#####################################" >> $Log
echo "$DATE TestServer Monitor Start!"   >> $Log
echo "#####################################" >> $Log

while [ 1 ]
do
        DATE=`date +%Y%m%d-%H%M%S`

        Cnt=`ps -ex|grep "TestServer"|grep -v grep|wc -l`

        if [ $Cnt \< 1 ]
        then
                PROCESS=`ps -ex|grep "TestServer"|grep -v grep|awk '{print $1}'`
                if [ "$PROCESS" != "" ]
                then
                        echo "$DATE : 프로세스를 종료합니다." >> $Log
                        kill -9 $PROCESS
                        wait
                fi

                echo "$DATE : Test 서버를 재 기동합니다." >> $Log
                 # 여기서 서버를 재기동한다.
                startServer.sh &

                echo "$DATE : Test 서버를 재 기동 완료." >> $Log

                sleep $PROB_SLEEP

                continue

        else
                echo "$DATE : 정상 작동중 입니다." >> $Log
        fi


        sleep $NORMAL_SLEEP

done
----------------------------------------------------------------------------------

여기까지 읽느라 고생많았으리라 생각한다.

좀더 멋진 생각을 더 첨가 할 수 있다.

실제로 나는 장애를 감지하는 별도의 프로그램을 작성하여 그 프로그램으로 실제적인 장애를 감지하고 

장애 발생시 SMS 프로그램을 통해 해당 담당자에게 SMS를 전송하고, 장애 복구 여부까지 자동으로 일괄 처리되도록 하는

나름대로 재미난 스크립트를 적용하여 무정지 서버를 운영중이다.

쉘을 가볍게 봤다간 큰코 다친다.

조금씩 공부하길 바라면서 글을 마친다. ^^