一、对于已定义的服务
1. 可以使用 linuxconf的图形化界面 来定义是否在系统启动时启动某项服务.
2. 使用/usr/sbin/ntsysv来定义
3. 使用chkconfig命令 来定义在那个运行级别是否运行某个服务器进程
若你希望在345运行级别下在启动时自动启动httpd服务器,则使用命令:
chkconfig --level 345 httpd on
若希望关闭该服务:
chkconfig --level 345 httpd off
4. 直接修改/etc/rc.d/rc*.d目录下的文件,这里*对应你要运行服务器的运行级别。例如你希望在运行级别3下启动域名服务器的named服务,则将K45named命名为:S80named即可:
move K45named S80named
也就是将K修改为S,并且将K后面的数字修改为一个合适的数字即可。
K表示停止,S表示启动,K后面的数字表示停止级别,S后面的数字表示启动级别
(参考http://www.irisbay.com/cgi-bin/webapp/index.cgi?action=viewnews&id=26)
二、自定义服务
已定义服务testsvc为例:
以root身份登录,在/etc/rc.d/init.d/目录新建testsvc脚本:
/etc/rc.d/init.d >vi testsvc
脚本内容:
#! /bin/sh
# chkconfig: 345 87 13
# description: Test Service
start() {
echo "start"
}
console() {
echo "console"
}
stop() {
echo "stop"
}
restart() {
echo "restart"
}
status() {
echo "status"
}
dump() {
echo "dump"
}
case "$1" in
'console')
console
;;
'start')
start
;;
'stop')
stopit
;;
'restart')
stopit
start
;;
'status')
status
;;
'dump')
dump
;;
*)
echo "Usage: $0 { console | start | stop | restart | status | dump }"
exit 1
;;
esac
保存,然后
>chmod 755 testsvc
测试脚本:
>testsvc start
配置服务
>chkconfig --add testsvc
测试是否配置成功
>chkconfig --list | grep testsvc
以上配置testsvc在runlevel 3/4/5三种模式自动启动,启动级别为87,停止级别为13。
一般的服务只要实现,start和stop即可。
三、使用wrapper自动启动java程序
对于java程序,可以用wrapper(可以从网上下载)来配置自启动。
参考wrapper和wrapper.conf
附:wrapper
==========================================================================================
#! /bin/sh
#
# Do not remove the following two lines
#
# chkconfig: 345 87 13
# description: Powsch Schedule Inc Service
# Application
APP_NAME="程序简称"
APP_LONG_NAME="程序全称"
# Wrapper命令
WRAPPER_CMD="/home/powsch/wrapper/wrapper"
#wrapper配置文件
WRAPPER_CONF="[路径]/wrapper.conf"
# Priority at which to run the wrapper. See "man nice" for valid priorities.
# nice is only used if a priority is specified.
PRIORITY=
# Location of the pid file.
# 进程号将保存到"程序简称.pid"文件中
PIDDIR="[pid文件存放路径]"
# If uncommented, causes the Wrapper to be shutdown using an anchor file.
# When launched with the 'start' command, it will also ignore all INT and
# TERM signals.
#IGNORE_SIGNALS=true
# If specified, the Wrapper will be run as the specified user when the 'start'
# command is passed to this script. When running with the 'console' command
# the current user will be used.
# IMPORTANT - Make sure that the user has the required privileges to write
# the PID file and wrapper.log files. Failure to be able to write the log
# file will cause the Wrapper to exit without any way to write out an error
# message.
# NOTE - This will set the user which is used to run the Wrapper as well as
# the JVM and is not useful in situations where a privileged resource or
# port needs to be allocated prior to the user being changed.
# 以下面的用户启动服务,可以注掉,表示以root启动
RUN_AS_USER=powsch
# 以下不必修改
#-----------------------------------------------------------------------------
# Get the fully qualified path to the script
case $0 in
/*)
SCRIPT="$0"
;;
*)
PWD=`pwd`
SCRIPT="$PWD/$0"
;;
esac
# Change spaces to ":" so the tokens can be parsed.
SCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'`
# Get the real path to this script, resolving any symbolic links
TOKENS=`echo $SCRIPT | sed -e 's;/; ;g'`
REALPATH=
for C in $TOKENS; do
REALPATH="$REALPATH/$C"
while [ -h "$REALPATH" ] ; do
LS="`ls -ld "$REALPATH"`"
LINK="`expr "$LS" : '.*-> /(.*/)$'`"
if expr "$LINK" : '/.*' > /dev/null; then
REALPATH="$LINK"
else
REALPATH="`dirname "$REALPATH"`""/$LINK"
fi
done
done
# Change ":" chars back to spaces.
REALPATH=`echo $REALPATH | sed -e 's;:; ;g'`
# Change the current directory to the location of the script
cd "`dirname "$REALPATH"`"
# Process ID
ANCHORFILE="$PIDDIR/$APP_NAME.anchor"
PIDFILE="$PIDDIR/$APP_NAME.pid"
pid=""
# Resolve the location of the 'ps' command
PSEXE="/usr/bin/ps"
if [ ! -x $PSEXE ]
then
PSEXE="/bin/ps"
if [ ! -x $PSEXE ]
then
echo "Unable to locate 'ps'."
echo "Please report this message along with the location of the command on your system."
exit 1
fi
fi
# Build the nice clause
if [ "X$PRIORITY" = "X" ]
then
CMDNICE=""
else
CMDNICE="nice -$PRIORITY"
fi
# Check the configured user
if [ "X$RUN_AS_USER" != "X" ]
then
# Resolve the location of the 'id' command
IDEXE="/usr/xpg4/bin/id"
if [ ! -x $IDEXE ]
then
IDEXE="/usr/bin/id"
if [ ! -x $IDEXE ]
then
echo "Unable to locate 'id'."
echo "Please report this message along with the location of the command on your system."
exit 1
fi
fi
if [ "`$IDEXE -u -n`" = "$RUN_AS_USER" ]
then
# Already running as the configured user. Avoid password prompts by not calling su.
RUN_AS_USER=""
fi
fi
getpid() {
if [ -f $PIDFILE ]
then
if [ -r $PIDFILE ]
then
pid=`cat $PIDFILE`
if [ "X$pid" != "X" ]
then
# Verify that a process with this pid is still running.
pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
if [ "X$pid" = "X" ]
then
# This is a stale pid file.
rm -f $PIDFILE
echo "Removed stale pid file: $PIDFILE"
fi
fi
else
echo "Cannot read $PIDFILE."
exit 1
fi
fi
}
testpid() {
pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1`
if [ "X$pid" = "X" ]
then
# Process is gone so remove the pid file.
rm -f $PIDFILE
fi
}
console() {
echo "Running $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
if [ "X$IGNORE_SIGNALS" = "X" ]
then
exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE
else
exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE
fi
else
echo "$APP_LONG_NAME is already running."
exit 1
fi
}
start() {
echo "Starting $APP_LONG_NAME..."
getpid
echo $pid
if [ "X$pid" = "X" ]
then
if [ "X$IGNORE_SIGNALS" = "X" ]
then
if [ "X$RUN_AS_USER" = "X" ]
then
exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE wrapper.daemonize=TRUE
else
su -m $RUN_AS_USER -c "exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE wrapper.daemonize=TRUE"
fi
else
if [ "X$RUN_AS_USER" = "X" ]
then
exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE wrapper.ignore_signals=TRUE wrapper.daemonize=TRUE
else
su -m $RUN_AS_USER -c "exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF wrapper.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE wrapper.ignore_signals=TRUE wrapper.daemonize=TRUE"
fi
fi
else
echo "$APP_LONG_NAME is already running."
exit 1
fi
}
stopit() {
echo "Stopping $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME was not running."
else
if [ "X$IGNORE_SIGNALS" = "X" ]
then
# Running so try to stop it.
kill $pid
if [ $? -ne 0 ]
then
# An explanation for the failure should have been given
echo "Unable to stop $APP_LONG_NAME."
exit 1
fi
else
rm -f $ANCHORFILE
if [ -f $ANCHORFILE ]
then
# An explanation for the failure should have been given
echo "Unable to stop $APP_LONG_NAME."
exit 1
fi
fi
# We can not predict how long it will take for the wrapper to
# actually stop as it depends on settings in wrapper.conf.
# Loop until it does.
savepid=$pid
CNT=0
TOTCNT=0
while [ "X$pid" != "X" ]
do
# Loop for up to 5 minutes
if [ "$TOTCNT" -lt "300" ]
then
if [ "$CNT" -lt "5" ]
then
CNT=`expr $CNT + 1`
else
echo "Waiting for $APP_LONG_NAME to exit..."
CNT=0
fi
TOTCNT=`expr $TOTCNT + 1`
sleep 1
testpid
else
pid=
fi
done
pid=$savepid
testpid
if [ "X$pid" != "X" ]
then
echo "Timed out waiting for $APP_LONG_NAME to exit."
echo " Attempting a forced exit..."
kill -9 $pid
fi
pid=$savepid
testpid
if [ "X$pid" != "X" ]
then
echo "Failed to stop $APP_LONG_NAME."
exit 1
else
echo "Stopped $APP_LONG_NAME."
fi
fi
}
status() {
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME is not running."
exit 1
else
echo "$APP_LONG_NAME is running ($pid)."
exit 0
fi
}
dump() {
echo "Dumping $APP_LONG_NAME..."
getpid
if [ "X$pid" = "X" ]
then
echo "$APP_LONG_NAME was not running."
else
kill -3 $pid
if [ $? -ne 0 ]
then
echo "Failed to dump $APP_LONG_NAME."
exit 1
else
echo "Dumped $APP_LONG_NAME."
fi
fi
}
case "$1" in
'console')
console
;;
'start')
start
;;
'stop')
stopit
;;
'restart')
stopit
start
;;
'status')
status
;;
'dump')
dump
;;
*)
echo "Usage: $0 { console | start | stop | restart | status | dump }"
exit 1
;;
esac
exit 0
======================================================================================
wrapper.conf
======================================================================================
#********************************************************************
# TestWrapper Properties
#
# NOTE - Please use src/conf/wrapper.conf.in as a template for your
# own application rather than the values used for the
# TestWrapper sample.
#********************************************************************
# Java Application
wrapper.java.command=java
# Java Main class. This class must implement the WrapperListener interface
# or guarantee that the WrapperManager class is initialized. Helper
# classes are provided to do this for you. See the Integration section
# of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=wrapper.jar的位置
wrapper.java.classpath.2=......
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=......
# Java Additional Parameters
wrapper.java.additional.1=其他的java命令行参数
wrapper.java.additional.2=......
# Initial Java Heap Size (in MB)
wrapper.java.initmemory=3
# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=64
# Application parameters. Add parameters as needed starting from 1
wrapper.app.parameter.1=包含main函数的java类
#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Format of output for the console. (See docs for formats)
wrapper.console.format=PM
# Log Level for console output. (See docs for log levels)
wrapper.console.loglevel=INFO
# Log file to use for wrapper output logging.
wrapper.logfile=wrapper日志文件
# Format of output for the log file. (See docs for formats)
wrapper.logfile.format=LPTM
# Log Level for log file output. (See docs for log levels)
wrapper.logfile.loglevel=INFO
# Maximum size that the log file will be allowed to grow to before
# the log is rolled. Size is specified in bytes. The default value
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
wrapper.logfile.maxsize=1m
# Maximum number of rolled log files which will be allowed before old
# files are deleted. The default value of 0 implies no limit.
wrapper.logfile.maxfiles=20
# Log Level for sys/event log output. (See docs for log levels)
wrapper.syslog.loglevel=NONE
#********************************************************************
# Wrapper Windows Properties
#********************************************************************
# Title to use when running as a console
wrapper.console.title=Smart Power Schedule Inc
#********************************************************************
# Wrapper Windows NT/2000/XP Service Properties
#********************************************************************
# WARNING - Do not modify any of these properties when an application
# using this configuration file has been installed as a service.
# Please uninstall the service before modifying this section. The
# service can then be reinstalled.
# Name of the service
wrapper.ntservice.name=powsch_inc
# Display name of the service
wrapper.ntservice.displayname=powsch_inc
# Description of the service
wrapper.ntservice.description=Smart Power Schedule Inc
# Service dependencies. Add dependencies as needed starting from 1
wrapper.ntservice.dependency.1=
# Mode in which the service is installed. AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# Allow the service to interact with the desktop.
wrapper.ntservice.interactive=false