Upstart 是一个由 Canonical 公司(就是开发 Ubuntu 的公司)开发和维护的一个的基于事件的开源 Linux 服务管理程序,它目标是替换掉基于 System-V 规范的 /sbin/init 程序。
为什么要用 Upstart ?
先说说传统的 System-V init(以下简称 SysVinit)的问题,SysVinit 只是简单地在系统启动、结束和切换预定义的几个 Runlevel 时根据文件名的顺序执行调用实现了 System-V 定义的服务控制脚本,就是大部分人熟悉的以下几个路径和里面的脚本内容格式:
/etc/inittab # 系统初始化过程的定义文件
/etc/init.d # 存放实际的服务控制脚本
/etc/rc?.d # 存放不同 Runlevel 对应 init.d 里的脚本的软连接
/etc/rc.* # 特定情况下执行的脚本
SysVinit 并不实际管理脚本具体做的事情,只要脚本能接受 start / restart / stop / status 等几个参数就视为符合定义(实际上即使不接受以上参数也可以放入 init.d 里让 SysVinit 调用,但会产生非预期的效果),对于服务是否正常启动,启动后是否异常退出,SysVinit 并不管理,这往往需要开发者在编写服务管理脚本时自行实现相关逻辑甚至编写额外的守护进程保证服务程序的可用性(MySQL 自带的 mysqld_safe 就是一个例子);
同时亦由于这个原因,SysVinit 无法处理服务之间的依赖关系,例如 Tomcat 依赖 MySQL,那么 Tomcat 启动之前需要先启动 MySQL,如果 MySQL 无法启动,Tomcat 也不应该启动,但由于 SysVinit 是顺序执行的,即使配置了先启动 MySQL 再启动 Tomcat,即使 MySQL 启动失败,Tomcat 依然会被启动,从而导致服务异常;
另外,由于顺序执行和无法感知服务之间的依赖关系,使得通过 SysVinit 实现服务并行启动加快系统启动速度的方案变得困难。Upstart 就是为了解决以上各种问题而被开发出来的。
怎样使用 Upstart 在 Ubuntu 6.0 以上版本就已经开始集成 Upstart,由于各个发行版及其各个版本安装 Upstart 的方式和集成度有一定差异,需要额外展开,所以这里先以 Ubuntu 系统基础操作环境。
Upstart 的所有服务管理脚本存放在
/etc/init/*.conf # 文件名就是 service name
脚本内容也不像 SysVinit 那样是一个普通的 shell 脚本,而是它预先规范好的一个配置文件(以下也称之为“配置文件”而非“脚本”),一个最基础的配置文件是这样的
description "MySQL Service"
start on runlevel [2345]
stop on runlevel [!2345]
exec /usr/bin/mysqld
整个配置文件非常简洁,第一行是服务描述,可有可无,但一般会写上以便理解,Upstart 保留了 Runlevel 的概念,这里定义了该服务在 runlevel 为 2 3 4 5 时启动该服务,而非这几个 Runlevel 时停止改服务,启动服务的命令为 /usr/bin/mysqld
。把该配置文件保存到
/etc/init/mysqld.conf
之后,我们就可以通过以下命令控制 MySQL Service 的启动状态
start mysqld # 启动
restart mysqld # 重启
stop mysqld # 停止
status mysqld # 检查状态
在服务启动之后,Upstart 会自动把该服务的标准输出(stdout)内容保存在 /var/log/upstart/(service-name).log
文件里,这个例子就是存放在 /var/log/upstart/mysqld.log
文件里,供有需要时查阅。
可能有部分熟悉 MySQL 的同学注意到,这里用的是 mysqld 而不是 mysqld_safe,这是因为 Upstart 本身会用一个独立的进程运行服务,不会让服务阻塞 shell,而且独立进程还会监控服务的存活状态,当发现服务退出后做其它相关处理。
What’s Next?
由于 Upstart 的功能丰富,这里不打算一次全部介绍完毕,将会分几篇介绍,下一篇会介绍服务的依赖管理,状态和事件的处理方式。
Coding 架构师 欧俊飞
【Coding 官方技术博客是 Coding 内部小伙伴在平时的工作学习过程中关于技术、产品、设计等等方面的积累和分享,希望大家共同学习共同进步!如转载,请注明出处与作者,谢谢!】