SaltStack通过Service方式管理服务,对于通用的服务,如mysql、apache、php等,自带service服务管理脚本,SaltStack可以方便管理。但是对于一些公司自有的服务,可能这些服务在开发之初,并没有考虑日后会采用Service脚本进行服务管理,为了统一Salt对服务的管理,我采用的方式是为每一个程序编写Service脚本。

这里主要注意以下三个问题:

1.这里有部分机器的优化,放在/etc/profile和/root/.bashrc中,而这两个文件在用户登陆的时候,会自动执行,而通过salt管理服务器,并不会执行这两个文件,所以在脚本中有导入这两个文件的操作;

2.之前服务启动的方式为nohup prog_name &这种形式,这个命令执行过后,还要有个敲回车键的操作,来确认结果输出到nohup.out文件,这里通过制定输出文件为nohup.out的方式,避免这个操作。

3.脚本的stop函数中,通过pidof命令获取进程的pid,然后通过kill杀掉,如果程序允许直接Kill掉,那么,使用pidof的方式要优于使用pkill、killall。

脚本如下:

#!/bin/sh
# FileName: mobile
# Description:  This shell script takes care of starting and stopping MobileStkServer
# Guibin created on Oct. 17th, 2014
# version 1.6-2015.04.29
# Source env
. /etc/profile
. /root/.bashrc
#the service name  for example: MobileStkServer
DAEN_NAME=MobileStkServer
DAEN_PATH=/home/MobileServer/

#the full path and name of the daemon DAEN_RUNram
#Warning: The name of executable file must be identical with service name
DAEN_RUN="nohup ./$DAEN_NAME > nohup.out 2>&1 &"

# check program file
check_profile(){
	PRO_FILE="$DAEN_PATH$DAEN_NAME"
	if [ ! -f "$PRO_FILE" ]
	then 
		echo "$PRO_FILE: No such file or directory"
		exit 1
	elif [ ! -x "$PRO_FILE" ]
	then
		echo "$PRO_FILE: Permission denied"
		exit 1
	fi
}

# status function
check_status(){
	check_profile
	DAEN_PID=''
	DAEN_PID=$(ps -ef|grep "$DAEN_NAME"|grep -v grep|awk '{print $2}')
		if [ -n "$DAEN_PID" ] 
		then
			DAEN_STATUS='sstart'
			return 0
		else
			DAEN_STATUS='sstop'
			return 1
		fi
}

status(){
	check_status
	if [ "$DAEN_STATUS"x == 'sstartx' ] 
	then
		echo -e "$DAEN_NAME is running with pid: $DAEN_PID"
		return 0
	else
		echo -e "$DAEN_NAME is not running!"
		return 1
	fi
}

# start function
start() {
    #check the daemon status first
	check_status
    if [ "$DAEN_STATUS"x == 'sstartx' ]
    then
        echo "$DAEN_NAME has already started!"
    else
        cd $DAEN_PATH
        printf "Starting $DAEN_NAME ..."
        eval $DAEN_RUN 
        sleep 2
        DAEN_PID=$(ps -ef|grep "$DAEN_NAME"|grep -v grep|awk '{print $2}')
        if [ -n "$DAEN_PID" ] 
        then
			echo -e "\t\t\t\t[ OK ]"
			echo -e "$DAEN_NAME is running with pid: $DAEN_PID"
        else
			echo -e "\t\t\t\t[ Failed ]"
			exit 1
        fi
    fi
}

#stop function
stop() {
	#check the daemon status first
	check_status
    if [ "$DAEN_STATUS"x == 'sstopx' ]
    then
        echo "$DAEN_NAME has already stopped!"
    else
		i=0
		while [ $i -lt 5 ]
		do
			`/sbin/pidof $DAEN_NAME |xargs /bin/kill > /dev/null 2>&1`
			sleep 2

			check_status
			if [ "$DAEN_STATUS"x == 'sstopx' ]
			then
				echo -e "Stopping $DAEN_NAME ...\t\t\t\t[ OK ]"
				break
			else
#				i=`expr $i + 1`
                i=$[$i+1]
			fi
		done

		check_status
		if [ "$DAEN_STATUS"x == 'sstartx' ]
		then
			echo -e "Stopping $DAEN_NAME ...\t\t\t\t[ Failed ]"
			exit 1
		fi
	fi
}

case "$1" in
start)
  start
  ;;
stop)
  stop
  ;;
reload|restart)
  stop
  sleep 2
  start
  ;;
status)
  status
  ;;
*)
  echo $"Usage: $0 {start|stop|restart|status|reload}"
  exit 1
esac

注:

    2014.12.25 程序启动命令增加标准错误重定向到标准输出 2>&1,否则新版Salt(2014.7.0)使用该脚本报错;

    2014.12.29 增加status函数返回值,否则在使用salt service.status查看进程状态时,被管理进程无论是否启动,都会返回True;