原文地址:http://blog.fens.me/linux-upstart/

upstart把应用封装成系统服务

ubuntu实用工具系列文章

操作系统实用工具系列文章,将介绍基于Linux ubuntu的各种工具软件的配置和使用。有些工具大家早已耳熟能详,有些工具经常用到但确依然陌生。我将记录我在使用操作系统时,安装及配置工具上面的一些方法,把使用心得记录下来也便于自己的以后查找和回忆。

关于作者

张丹(Conan), 程序员Java,R,PHP,Javascript
weibo:@Conan_Z
blog: http://blog.fens.me
email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/linux-upstart/

前言

对于使用linux的同学,敲大段的命令都已经是家长便饭了。但有些时候用命令也不是那么方便,比如启动一个后台程序, sh ./app & 执行启动命令很简单,如果想停止这个应用或者重启这个应用,就不是那么方便了。

如果能把应用封装成系统服务,那么就可以使用的 启动,重起,停止,状态检查等的标准方法了。应用会像一个守护程序一样,被操作系统所管理。

文章目录

  1. 初识upstart
  2. upstart任务文件的语法
  3. upstart命令
  4. upstart封装mytest
  5. 例子:upstart封装Nginx
  6. 例子:upstart封装MySQL
  7. 例子:upstart封装ssh

1. 初识upstart

说来惭愧,用了很多年的linux,也没有想法去怎么能优化一下应用启动。最近部署Nodejs应用时才发现,原来ubuntu有这么优雅的应用管理方式。

upstart可以用来代替/etc/init.d/的执行脚本,额外提供了一些特性,像速度,状态检查,简单定义任务等。

upstart两个核心点:事件(events),任务(jobs)

事件状态图

对状态的描述

  • waiting : initial state.
  • starting : job is about to start.
  • pre-start : running pre-start section.
  • spawned : about to run script or exec section.
  • post-start : running post-start section.
  • running : interim state set after post-start section processed denoting job is running (But it may have no associated PID!)
  • pre-stop : running pre-stop section.
  • stopping : interim state set after pre-stop section processed.
  • killed : job is about to be stopped.
  • post-stop : running post-stop section.

每个任务需要有一个配置文件,存放在/etc/init/目录下面。

~ vi /etc/init/mytest.conf

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

start mytest.conf

注:下面所有实例都以root权限进行操作

本文主要以实践为主。原理及更多细节介绍,请查看Upstart Cookbook:

http://upstart.ubuntu.com/cookbook/

2. upstart任务文件的语法

详细介绍: http://upstart.ubuntu.com/wiki/Stanzas
注:Stanzas的文档很多内容已经过期,建议参考cookbook或者man的使用帮助。

任务文件支持的语法关键字

Process Definition:
exec, script, pre-start, post-start, pre-stop, post-stop,

Event Definition:
start on, stop on, manual

Job Environment:
env, export

Services, tasks and respawning:
normal exit, respawn, respawn limit, task

Instances:
instance

Documentation:
description, author, version, emits, usage

Process environment:
console none,console log, console output, console owner, nice, limit, chroot, chdir, oom score, setgid, setuid, umask

Process Control:
expect fork, expect daemon, expect stop, kill signal, kill timeout

过期关键字:
service, daemon, pid

部分语法关键字介绍:

exec : 执行命令,在script块中使用。

语法:exec /usr/bin/zip -v

script: 脚本块,包括主运行脚本

语法:


scriptexec /usr/bin/zip /root/upstart.zip /root/upstart.txt
end script

pre-start: 脚本块,在主运行脚本之前执行的脚本

语法:


pre-start scriptexec rm /root/upstart.txtexec echo pre-start >> /root/upstart.txt
end script

post-start: 脚本块,在主运行脚本之后,running状态之前

语法:


post-start scriptexec echo post-start >> /root/upstart.txt
end script

pre-stop: 脚本块,在执行stop之前

语法:


pre-stop scriptexec echo pre-stop >> /root/upstart.txt
end script

post-stop: 脚本块,在主运行脚本被杀死之后

语法:


post-stop scriptexec echo post-stop >> /root/upstart.txt
end script

start on: 事件,启动任务

语法:

start on startup

stop on: 事件,停止任务

语法:

stop on shutdown

description: 描述,信息提示
语法:

description "This is a upstart testing."

author: 描述,作者信息
语法:

author "Conan_Z <bsspirit@gmail.com>"

version: 描述,版本信息
语法:

version "0.0.1 dev"

respawn: 命令,设置服务异常停止后自动重启
语法:

respawn

respawn limit: 命令,设置服务异常停止后重启次数及间隔时间
语法:

respawn limit 15 3

service: 命令,0.6版本后不再使用,被respawn取代

instance: 定义实例名字,可以通过命令给任务传参数
语法:


instance $TTY
exec /sbin/getty -8 38300 $TTY#通过命令传参数
~ start mytest $TTY=tty1

daemon: 作为守护进程的标志,0.5.0版本后被expect fork取代

kill timeout: 命令,在到达指定时间后,停止应用

语法:

kill timeout 5

kill timeout: 命令,正常退出,不会被respawn重启

语法:

normal exit 0 TERM

console: 命令,控制后输出,支持4种操作logged|output|owner|none

语法:

console owner

env: 变量,设置任务的环境变量

语法:

env PIDFILE=/var/run/myprocess.pid

umask: 变量,设置任务的文件权限的掩码

语法:

umask 0755

nice: 变量,设置任务的调度优先级

语法:

nice -5

limit: 变量,设置任务的资源限制

语法:

limit nproc 10 10

chroot: 变量,设置任务的根目录

语法:

chroot /var/lib/www/jail

chdir: 变量,设置任务的工作目录

语法:

chdir /var/tmp

3. upstart命令介绍

查看upstart版本

~ initctl version
init (upstart 1.5)

查看mytest应用状态

#方法1
~ initctl list|grep mytest
#方法2
~ status mytest

启动mytest应用

#方法1:
~ initctl start mytest
#方法2
~ start mytest

停止mytest应用

#方法1:
~ initctl stop mytest
#方法2
~ stop mytest

4. upstart封装mytest

用upstart写一个简单的应用脚本。

~ vi /etc/init/mytest.confdescription "mytest"
author "bsspirit <http://blog.fens.me>"env var=bar
export varstart on startup
stop on shutdownrespawn
respawn limit 2 5console outputpre-start scriptlogger "pre-start: before: var=$var"var=pre-startexport varlogger "pre-start: after: var=$var"
end scriptpost-start scriptlogger "post-start: before: var=$var"var=post-startexport varlogger "post-start: after: var=$var"
end scriptscriptlogger "script: before: var=$var"var=mainexport varsleep 60000logger "script: after: var=$var"
end scriptpost-stop scriptlogger "post-stop: before: var=$var"var=post-stopexport varlogger "post-stop: after: var=$var"
end script

测试mytest程序:

启动mytest任务


~ start mytest
mytest start/running, process 20682

查看日志跟踪运行状态


~ tail -f /var/log/syslogJun 21 08:11:21 li478-194 logger: pre-start: before: var=bar
Jun 21 08:11:21 li478-194 logger: pre-start: after: var=pre-start
Jun 21 08:11:21 li478-194 logger: script: before: var=bar
Jun 21 08:11:21 li478-194 logger: post-start: before: var=bar
Jun 21 08:11:21 li478-194 logger: post-start: after: var=post-start

查看mytest任务状态


~ status mytest
mytest start/running, process 20682

查看系统进程,因为在程序中用sleep停止,要通过sleep查询


~ ps -aux|grep sleeproot     20686  0.0  0.0   4304   352 ?        S    08:11   0:00 sleep 60000

杀掉sleep进程,mytest自动重启


~ kill -9 20686
~ ps -aux|grep sleep
root     20703  0.0  0.0   4304   344 ?        S    08:14   0:00 sleep 60000~ /var/log/syslog
Jun 21 08:15:59 li478-194 logger: post-stop: before: var=bar
Jun 21 08:15:59 li478-194 logger: post-stop: after: var=post-stop
Jun 21 08:15:59 li478-194 logger: pre-start: before: var=bar
Jun 21 08:15:59 li478-194 logger: pre-start: after: var=pre-start
Jun 21 08:15:59 li478-194 logger: script: before: var=bar
Jun 21 08:15:59 li478-194 logger: post-start: before: var=bar
Jun 21 08:15:59 li478-194 logger: post-start: after: var=post-start

停止mytest


~ stop mytest
mytest stop/waiting~ /var/log/syslog
Jun 21 08:16:49 li478-194 logger: post-stop: before: var=bar
Jun 21 08:16:49 li478-194 logger: post-stop: after: var=post-stop~ ps -aux|grep sleep

通过命令传参数,启动mytest


~ start mytest var=conan
mytest start/running, process 20735~ /var/log/syslog
Jun 21 08:18:51 li478-194 logger: pre-start: before: var=conan
Jun 21 08:18:51 li478-194 logger: pre-start: after: var=pre-start
Jun 21 08:18:51 li478-194 logger: script: before: var=conan
Jun 21 08:18:51 li478-194 logger: post-start: before: var=conan
Jun 21 08:18:51 li478-194 logger: post-start: after: var=post-start

不同参数,再次启动mytest


~ start mytest var=bsspirit
start: Job is already running: mytest

启动已经启动,禁止应用多次启动。
实验成功,我们可以很方便地利用upstart,来封装我们自己的应用成为系统服务。

下面将介绍同个软件使用upstart的例子。

5. upstart封装Nginx

Nginx官方配置:http://wiki.nginx.org/Upstart

增加配置文件


~ vi /etc/init/nginx# nginxdescription "nginx http daemon"
author "George Shammas <georgyo@gmail.com>"start on (filesystem and net-device-up IFACE=lo)
stop on runlevel [!2345]env DAEMON=/usr/sbin/nginx
env PID=/var/run/nginx.pidexpect fork
respawn
respawn limit 10 5
#oom neverpre-start script$DAEMON -tif [ $? -ne 0 ]then exit $?fi
end scriptexec $DAEMON

查看nginx的系统状态


~ initctl list | grep nginx

启动nginx


~ initctl start nginx

6. upstart封装MySQL

查看upstart配置文件,把MySQL变为系统服务.


~ vi /etc/init/mysql.confdescription     "MySQL Server"
author          "Mario Limonciello <superm1@ubuntu.com>"start on runlevel [2345]
stop on starting rc RUNLEVEL=[016]respawn
respawn limit 2 5env HOME=/etc/mysql
umask 007# The default of 5 seconds is too low for mysql which needs to flush buffers
kill timeout 300pre-start script#Sanity checks[ -r $HOME/my.cnf ][ -d /var/run/mysqld ] || install -m 755 -o mysql -g root -d /var/run/mysqld/lib/init/apparmor-profile-load usr.sbin.mysqldLC_ALL=C BLOCKSIZE= df --portability /var/lib/mysql/. | tail -n 1 | awk '{ exit ($4<4096) }'
end scriptexec /usr/sbin/mysqldpost-start scriptfor i in `seq 1 30` ; do/usr/bin/mysqladmin --defaults-file="${HOME}"/debian.cnf ping && {exec "${HOME}"/debian-start# should not reach this lineexit 2}statusnow=`status`if echo $statusnow | grep -q 'stop/' ; thenexit 0elif echo $statusnow | grep -q 'respawn/' ; thenexit 1fisleep 1doneexit 1
end script

7. upstart封装ssh


~ vi /etc/init/ssh.conf# ssh - OpenBSD Secure Shell server
#
# The OpenSSH server provides secure shell access to the system.description     "OpenSSH server"start on filesystem or runlevel [2345]
stop on runlevel [!2345]respawn
respawn limit 10 5
umask 022# 'sshd -D' leaks stderr and confuses things in conjunction with 'console log'
console nonepre-start scripttest -x /usr/sbin/sshd || { stop; exit 0; }test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }test -c /dev/null || { stop; exit 0; }mkdir -p -m0755 /var/run/sshd
end script# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
# 'exec' line here instead
exec /usr/sbin/sshd -D

我在这里介绍的内容还很初级,只要会写任务脚步就可以了。
后面文章我会介绍upstart封装nodejs,mongodb,php,java等的应用的任务脚本。

upstart把应用封装成系统服务相关推荐

  1. linux安装服务程序,将 Go 程序安装成系统服务

    在 Go 语言开发的程序部署到 Linux 服务器 这篇文章中提到了让应用程序在后台运行的方法,这篇文章讲的是如何将 Go 程序安装成系统服务(这篇文章中主要讲的 Windows 系统 和 Linux ...

  2. windows下redis安装,注册成系统服务

    前言 Redis-x64-3.0.504 win 7 目标:安装redis.redis 注册为系统服务,及异常处理 下载 https://github.com/microsoftarchive/red ...

  3. Nginx配置成系统服务

    经过前面的操作,我们会发现,如果想要启动.关闭或重新加载nginx配置文件,都需要先进入到nginx的安装目录的sbin目录,然后使用nginx的二级制可执行文件来操作,相对来说操作比较繁琐,这块该如 ...

  4. 服务助手NSSM——将Windows程序封装成服务

    文章目录 简介 安装 初试 删除服务 详细用法 服务依赖 进程优先级 关闭服务 退出和重启 I/O 文件轮换 环境变量 事件钩子 参考文献 简介 NSSM 可以将 Windows 程序封装成服务,当服 ...

  5. 【nssm将exe封装成服务】

    nssm使用 简介 下载地址 使用方式 以nacos为例 简介 nssm是一个服务封装程序,它可以将普通exe程序封装成服务,实现开机自启动. 下载地址 官网地址:https://nssm.cc/do ...

  6. 在 Debian 上将 aria2c 封装为服务的方法及遇到的踩坑点

    在 Debian 上将 aria2c 封装为服务的方法及遇到的踩坑点 问题起因 Aria2c 的用途就不介绍了,由于 aria2c 并没有提供服务封装,这就导致了如果需要启动.停止和重启时,都必须手工 ...

  7. Tomcat注册成系统服务并随机启动

    背景和问题:用了基于Java的单点登录Cas开源程序包,用上了Tomcat服务.但我们用上的是免安装版的tomcat程序包,运行tomcat程序时,会一直在任务栏.这样就会导致服务器重启的时候,都要手 ...

  8. JavaCV音视频开发宝典:无需流媒体服务也无需转码,使用JavaCV和springBoot实现http-flv转封装直播服务,浏览器网页flv.js直接播放rtp、rtsp、rtmp实时视频

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 本章代码除了在<JavaCV音视频开发宝典:使用JavaCV和spring ...

  9. linux 自启动服务 SYSV,技术|LFCS 系列第七讲:通过 SysVinit、Systemd 和 Upstart 管理系统自启动进程和服务...

    几个月前, Linux 基金会宣布 LFCS (Linux 基金会认证系统管理员) 认证诞生了,这个令人兴奋的新计划定位于让来自全球各地的初级到中级的 Linux 系统管理员得到认证.这其中包括维护已 ...

最新文章

  1. 需求简报_代码简报:有史以来最怪诞的丑毛衣
  2. 矩阵的逆矩阵怎么求_字节面试原题:求最大子矩阵的大小
  3. python基础教程:类和对象
  4. 理解Python中整型对象存储的位置
  5. jzoj3771-小Z的烦恼【高精度,数学】
  6. 问题解决: 此文件来自其他计算机,可能被阻止以帮助保护该计算机
  7. canny算法的实现(android加载图片,数组写入文件换行)
  8. python请输入_python中的三种输入方式
  9. HDU2010 水仙花数【进制+入门】
  10. 快速测试UTF8编码的文件是不是加了BOM,不限PHP
  11. PAIP.国内软件公司的现状及解决.txt
  12. 固高运动控制卡学习7 --模拟量
  13. es7 创建模板时,报错 Validation Failed: 1: index patterns are missing
  14. 计算机一级win7win10,一招win7免费升级成win10系统的简单方法(图文)
  15. # Windows下关于安装Geany编辑器过程中的一点小发现(可能对初次安装的人有用)
  16. python语言平台无关_从零开始学Python自然语言处理(十二)——上下文无关文法...
  17. C++函数之递归调用
  18. CSO关注:企业安全遭受攻击的15个迹象
  19. cmd 实用命令以及如何装逼
  20. Windows 7下的Excel 2010同时打开多个独立的窗口 [转]

热门文章

  1. 重磅,Flutter 1.9 正式发布!谷歌还为开发者带来了这些东西...
  2. ios企业号的ID更改
  3. mac格式化u盘,移动硬盘
  4. 数字水印Java写_Java实现数字水印
  5. 替代LT6711A功能方案| 完全替代LT6711A芯片|高性价比HDMI转EDP转换设计
  6. 关于tushare.get_h_data 返回数据值为空以及获取token码
  7. javascript语言简介
  8. 屏蔽和重启任务管理器
  9. 【MAPBOX基础功能】31、实现mapbox的测面功能
  10. 【MAPBOX基础功能】13、mapbox点击线图层高亮指定的线段