介绍
初始化是任何基于Unix的操作系统的核心,以控制每个脚本和服务的运行,这是在服务器环境中不可或缺的,在关键的启动和关闭点可能出现问题,并确保最佳性能是优先事项。
基本上,初始化遵循这种过程:
- 服务器启动
2 init 流程运行(通常作为
PID 1
) 3 一个预先定义的启动任务集在序列中激活
初始化负责确保云服务器可以清洁地启动和关闭。
一些具有 Unix 基础的发行版使用标准 init 程序进行初始化. 在本文中,我们将看看 Upstart – 一个实用而强大的替代程序,可以超载您的服务器操作。
经典 init 有什么不对劲?
传统的初始化遵循线性过程:单个任务在系统启动时以预定义的序列加载。这并不那么有用,尤其是在快速变化的情况下。
初始化过程无法考虑环境的突然变化,这意味着云服务器必须重新初始化才能识别额外的存储空间。
在线性序列中启动也需要时间,这在基于云的环境中尤其不利,其中快速部署至关重要。
您可能还担心系统加载后任务的状态,不幸的是,init只在启动或下载时关心序列。
同步启动序列不再是可取的,固态系统可以支持昨天的系统,但今天是动态的。
这就是 Upstart进入的地方 – 通过高级功能来解决这些问题。
基于 real-time 事件,而不是序列中的预设任务列表,这个替代 init daemon 处理任务的启动和停止 and 监控系统运行期间的这些流程 - 完整覆盖
是描述它的最佳方式。
这种新兴的非同步处理消除了对固态启动序列的需求. 实时处理可能难以概念化,但Upstart可以支持最复杂的系统,并通过使用 jobs的结构来控制一切。
关于Upstart的概述
从一开始就以灵活性设计,Upstart事件系统使用各种不同于传统初始化系统的概念,该解决方案默认安装在Red Hat Enterprise Linux (RHEL) 6上,以及谷歌的Chrome OS和Ubuntu上,尽管最近的辩论引发了关于这种情况是否会继续的混乱。
- 工作 *
在Upstart的世界中,工作是工作流程,分为任务工作(有目的)和服务工作(可以在背景中运行)。
- 事件 *
然而,事件是用来触发某项工作或其他事件的特定行动的信号或呼叫
,而常见的事件形式是指对一个过程的监控:开始
,开始
,停止
和停止
。
- 發表活動 *
这通常是由一个过程或工作状态引起的,虽然管理员也可以通过发出initctl emit <event>
命令来手动发出一个事件,你会注意到init control
命令在导航与Upstart相关的各种操作时变得非常有用。
写下你的第一份工作配置
Upstart在Ubuntu上表现良好,所以在启动之前,先打开一个 Ubuntu 14.04 Droplet。
现在你已经准备好了,重要的是要明白,工作配置文件必须遵循三个基本原则才能有效。
- 它不应该是空的(没有内容的文件)
- 它不应该包含任何语法错误
- 它必须包含至少一个命令块,称为 stanza
让我们把它留在现在的基本上。在一段时间内,我们将在/etc/init
目录中创建一个名为testjob.conf
的文件,在这种情况下,init
只是被用作initialization
的缩短版本。
注意.conf 文件关联 - 表示您将写一个 job 配置文件。
对于本教程的目的,建议使用命令行文本编辑器 nano. 其中一些命令可能需要具有sudo
的管理权限,所以请查看 本文 以创建合适的用户。
要为我们的测试工作创建一个新的配置文件,运行:
1sudo nano /etc/init/testjob.conf
现在让我们概述目标,我们希望这个工作 写一个消息和当前的时间戳到日志文件。
有两个基本的句子可以帮助您定义工作脚本的目的和谁创建它:描述
和作者
。
1description "A test job file for experimenting with Upstart"
2author "Your Name"
现在,我们希望该工作发生在系统服务和流程已经加载后(以防止任何冲突),所以您的下一行将包含以下事件:
1start on runlevel [2345]
基本上,它是一个单一的值,代表当前的系统配置. [2345]
指与一般的 Linux 访问和网络的所有配置状态,这是理想的基本测试示例。
然后我们将添加执行代码. 此行以exec
开头,表示下列命令应该通过Bash壳运行:
1exec echo Test Job ran at `date` >> /var/log/testjob.log
请注意,这个Echo
命令使用背杆来运行date
作为命令,然后将整个消息写入日志文件. 如果您没有背杆写入date
这个词,那么这个词本身将被打印而不是命令的输出。
保存并关闭此文件。
您可以通过手动启动工作来验证此功能,但让我们先检查配置文件语法:
1init-checkconf /etc/init/testjob.conf
如果发现任何问题,此命令会显示特定行号和问题,但是,在测试任务中,您应该看到这样的输出:
1File /etc/init/testjob.conf: syntax ok
此命令可用于控制 Upstart 工作和其他背景服务,例如 Web 服务器。
基本命令语法是:
1sudo service <servicename> <control>
此语法与这些基本控制器一起工作:
*重新启动:此将停止,然后启动服务 *启动:此将启动服务,如果不运行 *停止:此将停止服务,如果正在运行 *状态:此将显示服务的状态
我们想手动开始我们的测试工作,所以命令应该是这样的:
1sudo service testjob start
现在,通过运行以下命令检查testjob.log
文件:
1cat /var/log/testjob.log
这个命令会将文件读入壳中;你应该看到一个类似于下面的单行:
1Test Job ran at Fri Aug 1 08:43:05 BST 2014
这表明您的测试工作已设置并准备好进行。
重新启动您的 Droplet,然后登录并再次阅读日志文件:
1cat /var/log/testjob.log
您应该在日志中看到第二行显示更晚的时间标签,以确认它作为一个Upstart任务运行
测试工作运行于2014年8月1日 08:44:23 BST
这仅仅是对您可以使用 Upstart 做的事情的表面进行划痕,我们稍后将介绍一个详细的例子,但现在,让我们继续对工作状态和事件的解释。
工作状态和事件
系统工作位居 /etc/init/
目录,而用户工作位居用户自己的 init 目录, ~/.init/
。
用户工作在用户自己的会话中运行,所以它们也被称为会话工作,这些工作不会在整个系统中运行,也不属于PID 1
的指定。
无论其类型如何,任务在配置文件(.conf)中都定义为 ** always**,其文件名应该代表所涉及的服务或任务。
每个工作都有一个目标 - 要开始
或停止
。这两个目标之间是一组任务状态,这些状态定义了工作与目标有关的当前行动。
*等待:初始处理状态 *开始:工作即将开始 *预启:预启:预启部分被加载 *产生的:脚本部分即将运行 *后启动:后启动操作发生 *运行:工作完全运行 *预启动:前启动操作发生 停止:工作停止 *死亡:工作停止 后启动:后启动操作发生 清理
启动后状态后,该任务被定义为运行,直到启动预停为止,在那里该工作准备停止,然后该工作被杀死,如果定义,则发生后停止 **cleanup ** 程序。
您可以通过使用此命令将 Upstart 系统日志(位于 /var/log/upstart/
目录中)的优先级设置为 `debug' 来查看状态之间的工作过渡:
1sudo initctl log-priority debug
请记住, 状态不是事件,而事件不是状态. 四个事件(开始,开始,停止和停止)是由Upstart发出的,但任务状态定义了工作生命周期的阶段之间的过渡。
现在我们已经准备好转到一个更为集中的示例中,该示例通过写一份服务工作来集成您最初配置的元素,这将展示您如何从运行基本的测试配置过渡到生产准备的脚本。
深入的例子:服务工作
简要介绍,一个服务任务涉及编写脚本配置文件,允许流程在背景中运行,我们将从头开始设置一个 **基本 Node.js 服务器。
如果你不熟悉Node,它基本上是一个服务器侧和网络应用程序的跨平台环境
(维基百科)。
Node.js是一个非常轻量级的软件包,虽然它在Ubuntu 14.04上没有默认安装。
1sudo apt-get install nodejs
现在,让我们开始使用服务任务。在 /etc/init 中创建一个名为
nodetest.conf 的新工作配置文件. 根据其目的命名该文件是必不可少的,因此您将能够识别这个服务任务是用于 Node.js 测试的。
1sudo nano /etc/init/nodetest.conf
我们将在示例中稍后涵盖Node应用程序本身,因为重要的是事先了解Upstart配置。
首先,先输入职位描述和作者行来定义配置。
描述测试 node.js 服务器的服务
作者你的名字
我们希望这个由节点驱动的服务器应用程序在服务器启动和运行时启动,并在顺利关闭时停止。
1start on filesystem or runlevel [2345]
2stop on shutdown
还记得以前的运行水平标准吗?与文件系统
事件相结合,这将确保工作在服务器正常运行时加载。
这些是基本,但现在它变得更加复杂;我们将使用我们之前提到的 stanzas。
由于我们希望在 Node 应用程序启动和停止时登录,我们将使用三种不同的步骤来分离我们的服务操作 - 脚本
、预启动脚本
和预停止脚本
。
如果你认为这些听起来很熟悉,你绝对是对的。预先启动和预先停止是工作状态,但它们也工作在混乱中。
然而,写的第一个 stanza 是工作脚本本身. 这将为 Node 背景服务器获得一个进程 ID,然后运行应用程序脚本. 注意 stanza 中的命令的注入 - 这对于语法正确的格式化是必不可少的。
1script
2
3 export HOME="/srv"
4 echo $$ > /var/run/nodetest.pid
5 exec /usr/bin/nodejs /srv/nodetest.js
6
7end script
Node 需要设置一个主目录变量,这就是为什么 /srv' 被导出到 stanza 的第一行。接下来,
$$' 被用来获取可用的进程 ID,并为我们的工作创建一个 PID 文件。
现在是时候专注于预先开始
和预先停止
,这将用于我们简单的应用程序日志。
1pre-start script
2 echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
3end script
请注意,预停站包含另一个行:删除PID文件作为关闭服务器程序的一部分(预停操作)。
1pre-stop script
2 rm /var/run/nodetest.pid
3 echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
4end script
这是整个Upstart的工作配置排序;这里是整个东西再次参考:
1description "Test node.js server"
2author "Your Name"
3
4start on filesystem or runlevel [2345]
5stop on shutdown
6
7script
8
9 export HOME="/srv"
10 echo $$ > /var/run/nodetest.pid
11 exec /usr/bin/nodejs /srv/nodetest.js
12
13end script
14
15pre-start script
16 echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
17end script
18
19pre-stop script
20 rm /var/run/nodetest.pid
21 echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
22end script
保存并关闭文件。
正如在exec
行中所指出的那样,Node.js 脚本是从服务器运行的,所以在您想要的位置创建一个nodetest.js
文件(/srv/
用于此示例):
1sudo nano /srv/nodetest.js
由于这是一个 Upstart 教程,我们不会花太长时间来审查 Node.js 代码,尽管以下是该脚本将实现的概述:
- 要求并加载 Node 的 HTTP 模块
- 创建 HTTP 网页服务器
- 在 Header
中提供状态 200 (OK) 响应* 作为输出键入
Hello World
- 收听端口 8888
以下是您需要运行 Node 应用程序的代码,可以直接复制以节省时间:
1var http = require("http");
2
3http.createServer(function(request, response) {
4 response.writeHead(200, {"Content-Type": "text/plain"});
5 response.write("Hello World");
6 response.end();
7}).listen(8888);
保存 Node.js 文件后,最后要检查的是 Upstart 任务语法是否有效. 如往常一样,运行配置检查命令,您应该收到确认作为输出:
1init-checkconf /etc/init/nodetest.conf
文件 nodetest.conf:语法OK
你已经完成了工作配置,检查了它的语法,并保存了你的 Node.js 代码 - 一切都准备好了,所以重新启动你的 Droplet,然后访问 http://IP:8888,或相关的域。
如果你在窗口的左上角遇到Hello World
,Upstart服务工作已经起作用!
要确认基于状态的日志,请阅读预定义的日志文件,你应该看到一个时刻标记的开始
行. 关闭服务器或手动停止服务工作将写一个停止
行到日志中,如果你愿意,你也可以检查。
1cat /var/log/nodetest.log
2
3[Sun Aug 17 08:08:34 EDT 2014] Node Test Starting
4[Sun Aug 17 08:13:03 EDT 2014] Node Test Stopping
您可以为此服务运行 starstandard 开始、停止、重新启动等命令,以及任何其他类似的 Upstart 任务,语法如下:
1sudo service nodetest restart
结论
这个教程只会撕裂Upstart事件系统的表面,你已经阅读了传统初始化的背景,找到了为什么开源Upstart解决方案是一个更强大的选择,并开始写自己的工作。
来自Upstart官方网站的标志,版权原创设计师/Canonical Ltd。