如何使用Shell管理一个服务

针对一个服务,比如说C++服务工作在Linux环境环境下,因为它的启动往往伴随着一些环境变量的设置,或者依赖库的设置、或者特殊的启动方式,我们可能需要专门针对它写一个自动化管理的脚本,实现一键操作;

这里针对实际工作的需要与经验总结,特归纳一个管理服务生命周期的脚本,使用shell实现,实现了服务的启动、停止、周期性地监控,包括日志的转存的设置、watchdog脚本的自动生成等;

脚本的维护的地址是:

https://github.com/changshoumeng/projectMgr


#!/bin/bash
##########################################################
#	Teach Wisedom To Machine.
#	Please Call Me Programming devil.
#--------------------------------------------------------
#	ModuleName:server.sh
#	Note:/etc/rc.local
#-------------------------------------------------------
#   Usage:
#   if you project directory like this:
#   --project_root
#   ------lib
#   ------conf
#   ------bin
#   then you put this script into bin/;
#   ./server start	(will set dump_log,process_name,watch_dog)
#   ./server stop   (will try kill pid,then kill -9 pid if stop failed,and stop wath_dog)
#   ./server monit  (will check  the process running,start it if check process stopped)
#########################################################

#you must change it
SRC_PROCESS_NAME="loop_test"
SERVER_LOG_DIR=""

#you cannot change it
LOG_FILE="run.log"
PID_FILE="run.pid"
BASE_DIR=""
RUN_DIR=""
LIB_DIR=""
PROCESS_NAME=$SRC_PROCESS_NAME


function timeStamp(){
	date +'%Y/%m/%d %H:%M:%S'
}

function timeStamp2(){
   date +'%Y%m%d%H%M%S'
}

function logMessage(){
	echo $(timeStamp) $@
	echo $(timeStamp) $@>>$RUN_DIR/$LOG_FILE
}

function setEnv(){
  if [ -z "$BASE_DIR" ] ; then
	PRG="$0"
	while [ -h "$PRG" ] ; do
		ls=`ls -ld "$PRG"`
		link=`expr "$ls" : '.*-> \(.*\)$'`
		if expr "$link" : '/.*' > /dev/null; then
		  PRG="$link"
		else
		  PRG="`dirname "$PRG"`/$link"
		fi
	  done
	  BASE_DIR=`dirname "$PRG"`/..
	  BASE_DIR=`cd "$BASE_DIR" && pwd`
   fi
   RUN_DIR=$BASE_DIR/bin/run
   BIN_DIR=$BASE_DIR/bin
   LIB_DIR=$BASE_DIR/lib
   mkdir -p  $RUN_DIR
}

function setProcessName(){
	IS_CHECK_NAME=$1	
	if [ -z "$IS_CHECK_NAME" ] ;then
		IS_CHECK_NAME=1
	fi
	
	if [ $IS_CHECK_NAME -eq 0 ];then
		PROCESS_NAME=${BASE_DIR##*/}
		return
	fi
	
	if [ -f "$BIN_DIR/$SRC_PROCESS_NAME" ] ;then		
		NEWFILENAME=${BASE_DIR##*/}
		if [ "$NEWFILENAME" != "$SRC_PROCESS_NAME" ] ; then
			[ -f "$BIN_DIR/$NEWFILENAME" ] && mv "$BIN_DIR/$NEWFILENAME"  "${BIN_DIR}/${NEWFILENAME}_$(timeStamp2)"
			mv "$BIN_DIR/$SRC_PROCESS_NAME"  "$BIN_DIR/$NEWFILENAME"
			PROCESS_NAME=$NEWFILENAME
		fi
	else		
		PROCESS_NAME=${BASE_DIR##*/}
	fi
}


function setWatchDog(){
	DOGNAME="${PROCESS_NAME}_dog.sh"
	echo "set watchdog to $DOGNAME"
	if [ -f "$DOGNAME" ] ;then
		return 0
	fi
(
cat <<EOF
#!/bin/bash
#Teach wisedom to my machine
#zhangtao
#watch dog
#watchdog.sh

APPNAME=server.sh

while (true)
  do
		./server.sh monit
		sleep 10
  done
EOF
) > $DOGNAME
	chmod 777  "$DOGNAME"
}

function setServerDumpLog(){
	if [ -z "$SERVER_LOG_DIR" ] ;then
		if [ ! -d "log" ] ;then
			mkdir log
		fi
		return 1
	fi

	MYSERVER_LOG_DIR="${SERVER_LOG_DIR}/${PROCESS_NAME}"
	if [ -d "$MYSERVER_LOG_DIR" ] ;then
		echo "server_log_dir is $MYSERVER_LOG_DIR"
	else
		mkdir -p  "$MYSERVER_LOG_DIR"
		echo "create server_log_dir as: $MYSERVER_LOG_DIR"
	fi

	if [ ! -d "log" ] ;then
		ln -s  "$MYSERVER_LOG_DIR" log
	fi
}




function excuteCmdAndreportLog(){
	`eval $@`
	logMessage $@
}


function running(){
	if [ -f "$RUN_DIR/$PID_FILE" ]; then
			pid=$(cat "$RUN_DIR/$PID_FILE")
			if [ -z "$pid" ] ;then
				return 1
			fi

			pidlist=`pidof "$PROCESS_NAME"`
			if [ -z "$pidlist" ] ;then
				return 1
			fi

			if [[ "$pidlist" =~  "$pid" ]];then
					return 0
			else
					return 1
			fi
	else
			return 1
	fi
}



function start_server(){
	setProcessName
	setServerDumpLog
	if running ;then
		logMessage "$PROCESS_NAME is running ..."
		exit 1
	fi
	setWatchDog
	logMessage "----------------------------------> start_server	$PROCESS_NAME "
	logMessage "nohup $BIN_DIR/$PROCESS_NAME  2>&1 1>&/dev/null  &"
	export LD_LIBRARY_PATH=$LIB_DIR:$LD_LIBRARY_PATH
	echo $LIB_DIR
	chmod a+x $BIN_DIR/$PROCESS_NAME
	nohup $BIN_DIR/$PROCESS_NAME  2>&1 1>&/dev/null  &
	echo $! >$RUN_DIR/$PID_FILE
	excuteCmdAndreportLog "chmod 777 $RUN_DIR/$PID_FILE"
	sleep 2
	if running ;then
		logMessage "$PROCESS_NAME is running ...   "
		exit 1
	fi
	logMessage "$PROCESS_NAME start failed !"
}


function start_server_only(){
	if running ;then
		logMessage "$PROCESS_NAME is running ..."
		exit 1
	fi
	logMessage "----------------------------------> start_server_only	$PROCESS_NAME "
	logMessage "nohup $BIN_DIR/$PROCESS_NAME  2>&1 1>&/dev/null  &"
	export LD_LIBRARY_PATH=$LIB_DIR:$LD_LIBRARY_PATH
	echo $LIB_DIR
	chmod a+x $BIN_DIR/$PROCESS_NAME
	nohup $BIN_DIR/$PROCESS_NAME  2>&1 1>&/dev/null  &
	echo $! >$RUN_DIR/$PID_FILE
	excuteCmdAndreportLog "chmod 777 $RUN_DIR/$PID_FILE"
	sleep 2
	if running ;then
		logMessage "$PROCESS_NAME is running ...   "
		exit 1
	fi
	logMessage "$PROCESS_NAME start failed !"
}


function stop_server(){
	if ! running;then
		logMessage "$PROCESS_NAME was not running"
		exit 1
	fi

	DOGNAME="${PROCESS_NAME}_dog.sh"
	DOGPID=`ps -ef|egrep -i "bash"|egrep -i "$DOGNAME"|egrep -v "egrep"|awk '{print $2}'`
	if [ -n "$DOGPID" ] ;then
		 logMessage "$DOGNAME Work at $DOGPID"
		 excuteCmdAndreportLog "kill -9 $DOGPID"
	fi

	count=0
	pid=$( cat $RUN_DIR/$PID_FILE)
	while running; do
		let count=$count+1
		logMessage "stopping $PROCESS_NAME $count times !!!"
		if [ $count -gt 5 ] ;then
			excuteCmdAndreportLog "kill -9 $pid"
		else
			sleep 1
			excuteCmdAndreportLog "kill  $pid"
		fi
		sleep 2
	done
	logMessage "-----------> stop $PROCESS_NAME successfully <------------"
	excuteCmdAndreportLog "rm $RUN_DIR/$PID_FILE"
}

function monit_server(){
		if running ;then
				exit 1
		fi
		start_server_only $@
}

function status(){
	if running; then
	   logMessage "$PROCESS_NAME is running.";
	   exit 0;
	else
	   logMessage "$PROCESS_NAME was stopped.";
	   exit 1;
	fi
}



function help() {
	echo "------------------------------------------------------------------------------"
	echo "Usage: server.sh {start|status|stop|restart|logback}" >&2
	echo "		 start:				start the $PROCESS_NAME server"
	echo "		 stop:				stop the $PROCESS_NAME server"
	echo "		 monit:				monit the $PROCESS_NAME server"
	echo "		 restart:			restart the $PROCESS_NAME server"
	echo "		 logback:			reload logback config file"
	echo "		 status:			get $PROCESS_NAME current status,running or stopped."
	echo "-----------------------------------------------------------------------------"
}

function getOpts(){
	command=$1
	shift 1
	case $command in
		start)
			start_server $@;
			;;
		stop)
			stop_server $@;
			;;
		logback)
			reload_logback_config $@;
			;;
		status)
			status $@;
			;;
		monit)
			monit_server $@;
			;;
		restart)
			$0 stop $@
			$0 start $@
		  ;;
		help)
			help;
			;;
		*)
			help;
			exit 1;
			;;
	esac
}

function main(){
	setEnv $@
	setProcessName 0
	getOpts $@
}



main $@









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值