在项目中我们经常需要做的是,把我们写的应用封装成系统服务,那么它就会像一个守护程序一样,被操作系统所管理。目前linux有3种初始化系统,按出现的时间依次为init ,upstart和systemd。

 

3种系统简介

1. init

init即sysvinit,它是system v的成果,被推广到其他unix系统。常见的init 命令和/etc/init.d即属于它。

init的优点来自服务串行启动,可以保证脚本执行顺序,也方便调试和排错。但也因为串行启动导致系统启动时间很长,在linux被应用到移动端后这个缺点成了大问题。

2. upstart

upstart通过并行启动加快执行速度,但对于相互依赖的服务采用并发启动。它也支持硬件热插拔时的动态启动和卸载。

3.Systemd

systemd的并发更激进,因为对于相互依赖的服务它也同时启动。而且它的按需启动比upstart更优秀。

upstart取代了曾经辉煌的init,而systemd将要取代upstart

问题:

如何判断某个linux系统采用了哪种初始化系统?

初始化进程是kernel启动的第一个进程,其pid始终为1,因此我们可以使用stat /proc/1/exe可以查看:

#stat /proc/1/exe
  File: `/proc/1/exe' -> `/sbin/init'
  Size: 0               Blocks: 0          IO Block: 1024   symbolic link
Device: 3h/3d   Inode: 2608287784  Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-12-26 15:57:12.206286001 +0800
Modify: 2019-12-25 15:56:57.194347686 +0800
Change: 2019-12-25 15:56:57.194347686 +0800

或者根据/usr/lib/systemd /usr/share/upstart /etc/init.d这3个目录是否存在来判断。但是由于systemd和upstart都向后兼容,因此一个系统中可能安装了多个初始化系统。

UpStart

 

UpStart 基于事件机制,采用事件驱动机制也带来了一些其它有益的变化,比如加快了系统启动时间。采用这种事件驱动的模式,upstart 完美地解决了即插即用设备带来的新问题。

upstart两个核心点:事件(events),任务(jobs)。对于每个任务需要有一个配置文件,存放在/etc/init/目录下面。

~ vi /etc/init/mytest.conf

完成任务配置文件后,可以直接用initctl, start, stop 命令对任务进行启动,停止,查看状态 等的操作。

start mytest.conf

更多内容可参考Upstart Cookbook

配置

在/etc/init/目录下面,存放着各种各样的.conf文件,这些文件就是需要启动的服务进程的文件。系统会按照这些文件的内容,执行相应的内容。

一个conf文件的配置可能如下:

webapi_test.conf

description "webapi_test"

#设置资源限制
limit nofile 65535 65535


env JVM_CONFIG="-server -Xmx512m -Xms512m -Xmn256m -XX:SurvivorRatio=3  -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/heapdump.log -Xloggc:/usr/local/webapi_test/log/gc.log"

export JVM_CONFIG

env ROOT_DIR=/usr/local/webapi_test
export ROOT_DIR
env JAR_PACKAGE="webapi_test.jar"
export JAR_PACKAGE

start on started rc
stop on shutdown


respawn
# Respawning is subject to a limit. If the job is respawned more than COUNT times in INTERVAL seconds, it will be considered to be having deeper problems and will be stopped. Default COUNT is 10. Default INTERVAL is 5 seconds.
respawn limit 2 60

console output

pre-start script
        logger "pre-start begin: webapi_test"
        logger "pre-start end: webapi_test"
end script

post-start script
        logger "post-start begin: webapi_test"
        logger "post-start end: webapi_test"
end script

script
         logger "start begin: webapi_test"
         cd $ROOT_DIR
         mkdir -p $ROOT_DIR/log
         java $JVM_CONFIG -jar $JAR_PACKAGE >> $ROOT_DIR/log/webapi_test.log 2>&1
         logger "start end: webapi_test"
end script

post-stop script
        logger "post-stop begin: webapi_test"
        logger "post-stop end: webapi_test"
end script

conf文件的语法可以参考:http://upstart.ubuntu.com/wiki/Stanzas

总结:

关键字

用法

语法

示例

limit

为job流程设置资源限制。软限制和硬限制都需要。资源可以是:core cpu data fsize memlock msgqueue nice nofile nproc rss rtprio 

sigpending stack

limit resource <unlimited|soft> <unlimited|hard>

limit nofile 65535 65535

env

设置环境变量

env name=value

env PIDFILE=/var/run/myprocess.pid

start on 

设置什么时候start 

 start on event-name [args...]

start on startup

stop on

设置什么时候stop

stop on event-name [args...]

stop on shutdown

respawn 

为任务重启标志。重启标志意味着进程如果意外结束,将重新启动。

respawn

respawn

respawn limit

重启是有限制的。如果该job在间隔秒内被重新执行的次数超过计数次数,那么它将被认为存在更深层次的问题,并将被停止。默认计数为10。默认间隔为5秒。该配置只有在重启标志(即上面的respawn)被设置的时候才有效。

limit count timeout

respawn limit 15 5

console 

设置console的输出。有四个选择:logged|output|owner|none

logged:重定向到logger(默认设置)
output:直接输出到当前标准输出
owner:进程成为控制台的所有者,这意味着它可以接收来自键盘的信号
none:输出被重定向到/dev/null
 

console <logged|output|owner|none>

console owner

pre-start

指定在实际运行进程之前执行的命令

pre-start command

示例1:pre-start exec rm -f /usr/test.log

示例2:

pre-start script        rm -f /usr/share/hal/fdi/policy/gparted-disable-automount.fdiend script

script

运行任务进程的具体命令

script

some shell scripting

end script

script

  . /etc/default/hal

  exec /usr/sbin/hald --daemon=no $DAEMON_OPTS

end script

post-stop

主进程退出后,job停止时执行的命令。如果job无法启动主进程或启动前命令失败,则执行该命令。

post-stop command

post-stop script

        logger "service stop"

end script

使用

启动服务:start webapi_test

查看服务状态: status webapi_test

停止服务:stop webapi_test

 

 

参考文档:

upstart把应用封装成系统服务

Ubuntu的初始化系统工具Upstart