運維經驗分享(二)-- Linux Shell之ChatterServer服務控制腳本二次優化

運維經驗分享做爲一個專題,目前共7篇文章java

  1. 運維經驗分享(一)-- Linux Shell之ChatterServer服務控制腳本shell

  2. 運維經驗分享(二)-- Linux Shell之ChatterServer服務控制腳本二次優化編程

  3. 運維經驗分享(三)-- 解決Ubuntu下crontab不能正確執行Shell腳本的問題(一)bash

  4. 運維經驗分享(四)--關於 java進程管理的服務控制腳本編程思路分析運維

  5. 運維經驗分享(五)-- 改進的java進程管理的服務控制腳本async

  6. 運維經驗分享(六)-- 深究crontab不能正確執行Shell腳本的問題(二)ide

  7. 運維經驗分享(七)-- Linux Shell之ChatterServer服務控制腳本第三次優化優化

====================================分割線======================================this

最近開發人員提出新的需求,想將ChatterServer服務控制腳本放到ChatterServer根目錄下的bin目錄下,並向一次性能夠部署多個實例,所以這一個需求引起了多個改變:spa

1.再也不使用service進行控制,仍然保留status、start、stop和restart功能

2.BASEDIR再也不使用絕對路徑而要使用相對路徑,例如BASEDIR=..

3.SERVICEPORT要從ChatterServer根目錄下的conf目錄中的文件中讀取

4.日誌目錄logs將再也不手動建立,控制腳本須要本身建立logs目錄

針對以上4點變動,改進以下

1.去掉service控制,只須要將此腳本放到ChatterServer根目錄下的bin目錄下執行(實際上更簡單了)

2.既然要使用相對路徑而不使用絕對路徑就要正確設置Shell腳本的當前工做目錄,不然非但腳本很差用(log和pid都沒法正常生成),還會致使ChatterServer的核心命令行沒法使用(沒法讀取到相對路徑下的配置文件)

3.要想SERVICEPORT從ChatterServer根目錄下的conf目錄中的文件中讀取,很是簡單,但疑難問題在於排查上,例如grep對dos文件格式(file format)的文件很是不友好,會對腳本中後面的命令產生巨大影響(特別是echo以及變量(以$開頭的字符串)幾乎會亂掉),所以在使用grep前,必須將此文件的內容經過dos2unix命令來轉化,除非開發人員樂意將文件格式從dos手動改成unix(能夠參考《UNIX/Linux環境編程必須須要注意的問題總結》)

4.至關於多了一層異常檢測而已,比較簡單,看新的ChatterServer服務控制腳本就會明白。

通過二次「優化」改造的腳本以下:

#!/bin/bash
#chkconfig: 345 86 14
#description: Startup and shutdown script for ChatterServer(Port:$SERVICEPORT))
VERSION=1.0.0-snapshot
BASEDIR=..
# choose LOGDIR as standard of work directory
LOGDIR=$(pwd)/$BASEDIR/logs
if [[ ! -d $LOGDIR ]]; then
	mkdir $LOGDIR
fi
#SERVICEPORT=29093
#SERVICEPORT=`grep ^port $(pwd)/../conf/constant.properties | awk -F '=' '{print $2}'`
# NOTE: $(pwd)/../conf/constant.properties file fileformat must be unix NOT dos in shell scripts, or will cause some unknown error
# NOTE: grep is vrey sensitive to dos fileformat or unix fileformat
# apt-get install dos2unix
PORTFILE=$(pwd)/../conf/constant.properties
SERVICEPORT=$(cat $PORTFILE | dos2unix | grep ^port | awk -F '=' '{print $2}')
PIDFILE=$LOGDIR/chatter.pid
SERVER=$(pwd)/$BASEDIR/chatter-$VERSION\.jar
BASENAME=chatter
ARGS="-Xms2g -Xmx4g -Xmn4g -Xss128k -XX:MaxPermSize=64m -XX:-UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=30 -XX:SurvivorRatio=6"
# -Xms2g -Xmx2g -Xmn2g -Xss128k -XX:MaxPermSize=64m -XX:-UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=30 -XX:SurvivorRatio=6
status() {
    # The judgment priority: pid > port > piffile
    # netstat run by common user will get some error output, so we put those error outout to /dev/null
    if [[ $(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN) || -f $PIDFILE ]];then
        #pid=$(cat $PIDFILE)
        pid=$(ps -ef | grep java | grep $BASENAME | grep -v grep | awk '{print $2}')
        if [[ $pid != "" && $(ps -ef | grep $pid | grep -v grep) ]]; then
            echo "SUCCESS: ChatterServer(Port:$SERVICEPORT) is OK"
            exit 0
        else
            echo "ERROR: ChatterServer(Port:$SERVICEPORT) pid is NOT exist"
            exit 1
        fi
    elif [[ ! $(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN) ]]; then
            echo "ERROR: ChatterServer(Port:$SERVICEPORT) port is NOT listen"
            exit 1
    elif [[ ! -f $PIDFILE ]]; then
        echo "ERROR: ChatterServer(Port:$SERVICEPORT) pid file is NOT exist"
        exit 1
    else
        echo "ERROR:  ChatterServer(Port:$SERVICEPORT) is NOT running"
        exit 1
    fi
}

start() {
    if [[ -e $PIDFILE ]]; then
        echo "ERROR: pidfile $PIDFILE exist, ChatterServer(Port:$SERVICEPORT) has started with pid $(cat $PIDFILE)"
        # pid file can be deleted
        /bin/rm -f $PIDFILE
        exit 1
    fi
    if [[ -e $SERVER ]]; then
        echo "INFO: Starting ChatterServer(Port:$SERVICEPORT)"
        # Start ChatterServer core daemon
        # Why using "date +"%Y%m%d""? Because we just need restart this once per day
        # For ChatterServer wiil find some file in $BASEDIR
        cd $LOGDIR/../
        #nohup java -jar $SERVER $ARGS >>$LOGDIR/console-$(date +"%Y%m%d").out 2>&1 &
        java -jar $SERVER $ARGS >>$LOGDIR/console-$(date +"%Y%m%d").out 2>&1 &
        #java -jar $SERVER $ARGS >$LOGDIR/console.out 2>&1 &
        RETVAL=$?
        # shell do NOT need home directory
        ## For ChatterServer wiil find some file in $BASEDIR
        cd  $LOGDIR/../bin
        if [[ $RETVAL -eq 0 ]]; then
            ## $! --> Expands to the process ID of the most recently executed background (asynchronous) command.
            #echo $! > $PIDFILE
            # For java performance issue, port 29092 will listen latter, we will waiting for 2 second
            sleep 2
            # get pid var
            # TODO remove debug info
            #echo "DEBUG: "
            #ps -ef | grep $BASENAME | grep -v grep | awk '{print $2}'
            # end debug
            #pid=$(ps -ef | grep java | grep $BASENAME | grep -v grep | awk '{print $2}')
            pid=$(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN | awk '{print $7}' | awk -F '/' '{print $1}')
	    # send pid number to pid file
            echo $pid > $PIDFILE
            # Those lines will remove in next release
            # TODO remove debug info
            #echo "DEBUG: live 1"
            # For java performance issue, port 29092 will listen latter, so we change judgment conditions
            if [[ $(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN) || -f $PIDFILE ]]; then
                echo "SUCCESS: ChatterServer(Port:$SERVICEPORT) start OK"
                # Setting up start log 
                echo "[ $(date +"%D %T") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) started with pid $(cat $PIDFILE) " >>$LOGDIR/service.log
            fi
            # TODO remove debug info
            #echo "DEBUG: live 2"
            # -Those lines will remove in next release
            #echo "SUCCESS: ChatterServer start OK"
            ## Setting up start log 
            #echo "[ $(date +"%D %T") ] SUCCESS: ChatterServer started with pid $(cat $PIDFILE) " >>$LOGDIR/service.log
        else
            echo "ERROR: ChatterServer(Port:$SERVICEPORT) start failed"
            # Setting up start log 
            echo "[ $(date +"%D %T") ] ERROR: ChatterServer(Port:$SERVICEPORT) start failed " >>$LOGDIR/service.log
            exit $RETVAL
        fi
    else
        echo "ERROR: Couldn't find $SERVER"
        # TODO We just think this is not essential
        # Do NOT setting up log here
        exit 1
    fi

}
stop() {
    if [[ -e $PIDFILE ]]; then
        pid=$(cat $PIDFILE)
        #if kill -TERM $PIDFILE >/dev/null 2>&1
        # TODO remove debug info
        #echo "DEBUG: $LOGDIR/console-$(date +"%Y%m%d").out"
        # Ubuntu can NOT use "usleep", so use "sleep" instead
        # usleep 100000 
        if kill -TERM $pid >>$LOGDIR/console-$(date +"%Y%m%d").out && sleep 1
            then
            echo "SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with TERM"
            # Setting up stop log 
            echo "[ $(date +"%D %T") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with TERM " >>$LOGDIR/service.log
            # Because we can NOT use usleep , so we must comment out sleep 1 next
            #sleep 1
            # Ubuntu can NOT use "usleep", so use "sleep" instead
            # usleep 100000 
        elif kill -KILL $pid >/dev/null 2>&1 && sleep 1
            then
            echo "SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with KILL"
            # Setting up stop log 
            echo "[ $(date +"%D %T") ] SUCCESS: ChatterServer(Port:$SERVICEPORT) stop OK with KILL " >>$LOGDIR/service.log
            # Because we can NOT use usleep , so we must comment out sleep 1 next 
            #sleep 1
        else
            echo "ERROR: ChatterServer(Port:$SERVICEPORT) stop faild"
            # Setting up stop log 
            echo "[ $(date +"%D %T") ] ERROR: ChatterServer(Port:$SERVICEPORT) stop failed " >>$LOGDIR/service.log
            exit 1
        fi
        # Remove pid file
        if [[ -f $PIDFILE ]]; then
            /bin/rm -f $PIDFILE
        fi
    else
        echo "ERROR: No ChatterServer(Port:$SERVICEPORT) running"
        # TODO We just think this is not essential
        # Do NOT setting up log here
        exit 1
    fi
}

restart() {
    echo "INFO: Restarting ChatterServer(Port:$SERVICEPORT)"
    stop
    # Those lines will remove in next release
    if [[ $(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN) ]]; then
        echo "WARNNING: port $SERVICEPORT is in using, must waiting"
        sleep 5
        if [[ $(netstat -anop 2>/dev/null | grep $SERVICEPORT | grep LISTEN) ]]; then
            echo "WARNNING : port $SERVICEPORT is still in using, must waiting"
            sleep 2
        fi
    fi
    # -Those lines will remove in next release
    # Do NOT using sleep any seconds here with stop() function used
    start
}

case $1 in
    status)
        status
        ;;
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    help|*)
        echo "Usage: $0 {status|start|stop|restart|help} with $0 itself"
        exit 1
        ;;
esac
# replace "exit 0" with ":"
#exit 0
:

--end--

====================================分割線======================================

運維經驗分享做爲一個專題,目前共7篇文章

  1. 運維經驗分享(一)-- Linux Shell之ChatterServer服務控制腳本

  2. 運維經驗分享(二)-- Linux Shell之ChatterServer服務控制腳本二次優化

  3. 運維經驗分享(三)-- 解決Ubuntu下crontab不能正確執行Shell腳本的問題(一)

  4. 運維經驗分享(四)--關於 java進程管理的服務控制腳本編程思路分析

  5. 運維經驗分享(五)-- 改進的java進程管理的服務控制腳本

  6. 運維經驗分享(六)-- 深究crontab不能正確執行Shell腳本的問題(二)

  7. 運維經驗分享(七)-- Linux Shell之ChatterServer服務控制腳本第三次優化

相關文章
相關標籤/搜索