如何配置Linux的服务设置为自动启动或崩溃重新启动后

介绍

在本教程中,自动启动 Linux 服务,我们将退后一步,更详细地解释 init 进程。 你应该很好地了解它们如何控制守护进程的启动行为。

在第一部分本系列教程我们分享使用 MySQL 的如何崩溃或重启后启用的 Linux 服务自动启动一些实际的例子。

我们看到了如何从三个不同的初始化方式做到这一点:System V 的,Upstart,和 systemd。 阅读第一个教程在其上分布在默认情况下使用的 init 系统的复习。

在本教程中,我们将退后一步,解释为什么我们运行命令并编辑我们所做的配置文件。 我们将从 System V init 守护进程开始。 我们还将看到为什么它随着时间的推移被更新的 init 模式所取代。

先决条件

要学习本教程,你需要你创建的三个 DigitalOceanDroplet 之前 。

我们有:

  •  运行 MySQL 的 Debian 6 服务器
  •  一个运行 MySQL 的 Ubuntu 14.04 服务器
  •  运行 MySQL 的 CentOS 7 服务器

我们建议您回到本系列的第 1 部分,先创建 Droplets。

此外,您将需要是 root 用户或在服务器上具有 sudo 权限。 要了解 sudo 的权限是如何工作的看到有关这个 Sudo 教程 DigitalOcean 。

您不应在生产 Linux 服务器上运行本教程中的任何命令,查询或配置。

运行级别

运行级别代表了 Linux 系统的当前状态。

该概念来自 System V init,其中 Linux 系统引导,初始化内核,然后输入一个(且只有一个)运行级别。

例如,运行级可以是 Linux 服务器的关闭状态,单用户模式,重新启动模式等。每个模式将指示什么服务可以在该状态下运行。

某些服务可以在一个或多个运行级别运行,但不能在其他运行级别运行。

运行级别由单个数字表示,它们可以具有介于 0 和 6 之间的值。以下列表显示了这些级别各自的含义:

  •  运行级别 0:系统关闭
  •  运行级别 1:单用户,救援模式
  •  运行级别 2,3,4:多用户,与网络文本模式下启用
  •  运行级别 5:多用户,启用网络,图形模式
  •  运行级别 6:系统重启

运行级别 2,3 和 4 因分布而异。 例如,一些 Linux 发行版不实现运行级别 4,而其他的。 一些分布在这三个级别之间有明显的区别。 通常,运行级别 2,3 或 4 意味着 Linux 已在多用户,启用网络的文本模式下引导的状态。

当我们启用一个服务自动启动,我们实际上是将它添加到运行级别。 在系统 V 中,OS 将以特定的运行级别开始; 并且,当它启动时,它将尝试启动与该运行级别相关联的所有服务。

运行级别成为 systemd 的目标 ,我们将在 systemd 部分讨论。

Init 和 PID 1

初始化是在计算机启动和内核加载到内存中后,开始在 Linux 系统中的第一个进程。

除此之外,它决定了用户进程或系统服务应该按什么顺序加载,以及是否应该自动启动。

在 Linux 中每个进程都有一个进程 ID(PID)和init有 1. PID 就这么随后产卵系统自带的在线所有其他进程的父。

Init 的历史

随着 Linux 的发展,init 守护进程的行为也发生了变化。 最初,Linux 开始使用 System V init,与 UNIX 中使用的相同。 自那时以来,Linux 已经实施了Upstart的 init 守护进程(被 Ubuntu 创建)现在systemd的 init 守护进程(最初由 Fedora 的实现)。

大多数 Linux 发行版已逐渐从 System V 迁移或逐步淘汰,只保留向后兼容性。 FreeBSD 是 UNIX 的一种变体,它使用 System V 的不同实现,称为 BSD init。 旧版本的 Debian 也使用 SysVinit。

每个版本的 init 守护程序都有不同的管理服务的方式。 这些变化背后的原因是需要一个强大的服务管理工具,不仅处理服务,而且处理设备,端口和其他资源; 这将并行加载资源,这将从崩溃恢复。

系统 V 初始化序列

系统 V 使用了inittab文件,它像 Upstart 后的 init 方法已经保持向后兼容性。

让我们通过 System V 的启动顺序:

  1.  在 init 守护进程从二进制文件创建/sbin/init
  2.  第一个文件在 init 守护进程是读取/etc/inittab
  3.  此文件中的一个条目决定机器应引导到的运行级别。 例如,如果运行级别的值指定为 3,则 Linux 将在启用了联网的多用户文本模式下启动。 (此运行级别称为默认运行级别)
  4.  接下来,init 守护进程会进一步眺望/etc/inittab的文件和在读什么初始化它需要为运行级别的脚本

因此,当 init 守护进程找到它需要为给定的运行级别运行的 init 脚本时,它基本上找出了启动它需要什么服务。 这些 init 脚本是您可以在其中配置单个服务的启动行为,就像我们在第一个教程中对 MySQL 的启动行为一样。

接下来,让我们详细了解 init 脚本。

系统 V 配置文件:Init 脚本

init 脚本是控制系统 V 中的特定服务(如 MySQL 服务器)的脚本。

服务的 Init 脚本由应用程序的供应商提供,或者带有 Linux 发行版(适用于本地服务)。 我们还可以为自定义创建的服务创建自己的 init 脚本。

当一个进程或服务(如 MySQL 服务器)启动时,其二进制程序文件必须加载到内存中。

根据服务的配置,此程序可能必须持续在后台执行(并接受客户端连接)。 启动,停止或重新加载此二进制应用程序的任务由服务的 init 脚本处理。 这就是所谓的初始化脚本,因为它初始化服务。

在 System V 中,init 脚本是 shell 脚本。

初始化脚本也被称为RC(运行命令)的脚本。

目录结构

/etc目录是启动脚本的父目录。

init 的 shell 脚本的实际位置是在/etc/init.d 。 这些脚本符号链接到rc目录。

/etc目录下,我们有一些rc目录,每一个在其名称中的数字。

数字表示不同的运行级别。 因此,我们有/etc/rc0.d , /etc/rc1.d , /etc/rc2.d等等。

然后,每个内rc n .d目录,我们有一个既具有开始的文件KS在他们的文件名,后面两个数字。 这些是指向实际 init shell 脚本的符号链接文件。 为什么KS ? K 表示停止(即停止),“S”表示开始。

两个数字表示脚本的执行顺序。 因此,如果我们有一个名为 K25 some_script文件,它将 K99 another_script之前执行。

启动

让我们回来跟我们的启动顺序。 那么如何调用 init 脚本呢? 谁叫他们?

在 K 和 S 脚本不会由 init 守护程序直接调用,而是由另外一个脚本:在/etc/init.d/rc脚本。

如果你还记得,在/etc/inittab的文件通知 init 守护进程的运行级别,系统默认情况下应进入。 对于每一个运行级别,在一条线/etc/inittab文件调用/etc/init.d/rc脚本,传递上的运行级别作为参数。 基于此参数,脚本然后调用相应的下的文件/etc/rc n .d目录。 所以,如果服务器靴子的 runlevel 2,根据脚本/etc/rc2.d会被调用; 为级别 3,根据脚本/etc/rc3.d被执行,等等。

在一个rc目录,首先,所有 K 个脚本都按数字顺序以“一站式”的参数运行,然后所有的 S 脚本都以类似的方式用的参数运行“开始。” 在后台,将分别使用 stop 和 start 参数调用相应的 init shell 脚本。

现在,因为下的文件/etc/rc n .d目录( K nnnn文件)符号链接而已,美其名曰意味着调用与站的实际初始化 shell 脚本和启动参数。

总而言之,当 Linux 服务器进入运行级别时,将运行某些脚本以停止某些服务,而其他脚本将运行以启动其他服务。

启动脚本中调用这个也恰好当系统切换到一个新的运行级别:对应/etc/rc<n>.d目录的脚本执行。 而且,由于这些钾和硫的文件是什么,但环节,根据实际的 shell 脚本/etc/init.d目录与相应的启动执行或停止争论。

整个过程确保任何不应该在该运行级别运行的服务被停止,并且所有服务应该在该运行级别运行。

系统 V 自动启动

由于我们使服务在引导时自动启动,我们实际上是修改 init 行为。

因此,例如,当我们在运行级别 3 使能自动启动服务,幕后的过程中会在适当的环节/etc/rc3.d目录。

如果这听起来很混乱,不要担心 – 我们会在一分钟内看到这一切意味着什么。

系统 V 示例

我们将回到我们的 MySQL 服务示例,这次有更多的理论。

第 1 步 – 登录 Debian Droplet

为了本教程的这一部分,我们将回到我们在第 1 部分中创建的 Debian 6 Droplet。使用 SSH 命令连接到服务器(Windows 用户可以使用像 PuTTy 这样的工具连接)。

ssh sammy@your_server_ip

第 2 步 – 查看 inittab

运行以下命令来查看inittab文件的内容:

cat /etc/inittab | grep initdefault

输出应该是这样的:

id:2:initdefault:

2 后的 id 字段显示系统被配置为以 runlevel 2 开始。这是默认的运行级别。 在这种情况下,Debian 将 2 指定为多用户文本模式。 如果执行以下命令:

cat /etc/inittab | grep Runlevel

输出确认:

# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.

第 3 步 – 查看 rc 目录

运行以下命令列出rc目录。 你应该看到有以下六个:

ls -ld /etc/rc*.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc0.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc1.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc2.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc3.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc4.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc5.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc6.d
drwxr-xr-x 2 root root 4096 Jul 23  2012 /etc/rcS.d

由于在运行级别 2(从 inittab 文件默认的 init)在系统启动时,根据脚本/etc/rc2.d的目录会在系统启动时执行。

列出此目录的内容:

ls -l /etc/rc2.d

这显示文件只是符号链接,每个指向/etc/init.d 下的脚本文件:

. . .
lrwxrwxrwx 1 root root  17 Jul 23  2012 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root  22 Jul 23  2012 S02acpi-support -> ../init.d/acpi-support
lrwxrwxrwx 1 root root  15 Jul 23  2012 S02acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root  17 Jul 23  2012 S02anacron -> ../init.d/anacron
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02atd -> ../init.d/atd
lrwxrwxrwx 1 root root  14 Jul 23  2012 S02cron -> ../init.d/cron
lrwxrwxrwx 1 root root  15 Jul 31 07:09 S02mysql -> ../init.d/mysql
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02ssh -> ../init.d/ssh
. . .

我们可以看到这里没有 K 脚本,只有 S(start)脚本。 脚本启动知名的服务,如rsyslog 现在 ,cron 的 ,或ssh。

记住,S 之后的两个数字决定起始顺序:例如,rsyslog 在 cron 守护程序之前启动。 我们还可以看到 MySQL 在这里列出。

第 4 步 – 查看 Init 脚本

现在我们知道,安装在系统 V 兼容的服务时,它会创建下 shell 脚本/etc/init.d目录。 检查 MySQL 的 shell 脚本:

ls -l /etc/init.d/my*
-rwxr-xr-x 1 root root 5437 Jan 14  2014 /etc/init.d/mysql

要查看启动脚本的外观,请阅读文件:

cat /etc/init.d/mysql | less

从输出,你会看到它是一个大的 bash 脚本。

第 5 步 – 使用 chkconfig 或 sysv-rc-conf

在基于 RHEL 的发行像 CentOS 的,一个命令调用chkconfig可以用来启用或系统五,禁用服务,它还可以列出已安装的服务和他们的运行级别。

检查 CentOS 系统上所有运行级别的服务状态的语法如下:

chkonfig --list | grep service_name

没有这样的工具附带的 Debian 本身( update-rc.d安装或只从运行级别删除服务)。 我们可以,但是,安装定制的工具,称为sysv-rc-conf帮助我们管理服务。

运行以下命令来安装sysv-rc-conf :

sudo apt-get install sysv-rc-conf -y

安装工具后,只需执行此命令即可查看各种服务的运行级别行为:

sudo sysv-rc-conf

输出将是一个漂亮的图形窗口,如下所示。 从这里,我们可以清楚地看到什么服务启用了什么运行级别(标记为 X)。

sysv-rc-conf 显示每个运行级别的各种服务的 X 标记的窗口

利用箭头键和SPACEBAR ,可以启用或对一个或多个运行级别禁用服务。

现在,按离开屏幕Q 。

第 7 步 – 在引导时测试 MySQL 启动行为

从上一节的截图中可以看出,根据我们在本教程第 1 部分的测试,MySQL 目前在运行级别 2-5 上启用。

运行下面的命令关闭 MySQL 服务:

sudo update-rc.d mysql disable
update-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `mysql' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `mysql' overwrites defaults (0 1 6).

现在运行命令:

ls -l /etc/rc2.d

输出应显示从符号链接/etc/rc2.d/etc/init.d/mysql已更改为K :

. . .
lrwxrwxrwx 1 root root  15 Jul 31 07:09 K02mysql -> ../init.d/mysql
. . .

换句话说,MySQL 将不再在默认 runlevel(2)启动。

这是当我们启用和禁用服务时,在 System V 的幕后发生的。 只要在服务的缺省 runlevel 目录下有一个 S 脚本,init 将在启动时启动该服务。

再次启用服务:

sudo update-rc.d mysql enable

第 8 步 – 测试崩溃时 MySQL 启动行为

让我们看看 System V 如何处理服务崩溃。

请记住,我们做了一个改变了/etc/inittab在本教程的第 1 部分文件,以使 MySQL 的系统崩溃后自动启动。 我们添加了以下行:

/ etc / inittab
ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe

这是为了确保 MySQL 服务在崩溃后启动。 要检查是否发生这种情况,请首先重新启动服务器:

sudo reboot

一旦服务器回来,SSH 到它并检查 MySQL 进程 ID 像之前一样:

ps -ef | grep mysql

注意进程 ID mysqld_safemysqld 。 在我们的例子中,分别是 895 和 1019:

root       907     1  0 07:30 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql     1031   907  0 07:30 ?        00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306
root      1032   907  0 07:30 ?        00:00:00 logger -t mysqld -p daemon.error
root      2550  2532  0 07:31 pts/0    00:00:00 grep mysql

有一次终止这些进程-9开关(替代与 Debian 系统的 PID):

sudo kill -9 907
sudo kill -9 1031

<! – 标记变量为红色 – >

等待五分钟左右,然后执行命令:

sudo service mysql status

输出将显示 MySQL 服务正在运行,从这行开始:

/usr/bin/mysqladmin  Ver 8.42 Distrib 5.1.73, for debian-linux-gnu on x86_64

如果您运行ps -ef | grep mysql ps -ef | grep mysql命令再次,你会看到,无论是mysqld_safemysqld进程已经上来了。

尝试杀死进程几次,在每种情况下,它应该在五分钟后重生。

这是我们增加的原因,额外行/etc/inittab :你这是怎么配置的 System V 服务崩溃重生。 还有就是语法此行的详细解释第 1 部分 。

但是,为服务添加自动重新启动时请小心:如果服务尝试重新生成并在两分钟内失败超过十次,则 Linux 将禁用在接下来的五分钟内重新启动。 这就是系统保持稳定,不会耗尽计算资源。

如果您碰巧在控制台中收到有关此类事件的消息或在系统日志中找到该消息,您将知道应用程序存在需要修复的问题,因为它会持续崩溃。

Upstart 简介

经典 SysVinit 在 Upstart 出现之前已经成为主流 Linux 发行版的一部分。

随着 Linux 市场的增长,加载作业和服务的序列化方法变得更加耗时和复杂。 与此同时,随着越来越多的现代设备(如可热插拔的存储介质)激增了市场,SysVinit 被发现无法快速处理它们。

需要更快的加载操作系统,正常清理崩溃的服务,以及可预测的系统服务之间的依赖驱动了对更好的服务管理器的需要。 Ubuntu 的开发人员提出了另一种初始化方法,即 Upstart 守护进程。

Upstart init 在几个方面优于 System V init:

  •  Upstart 不处理奥术 shell 脚本加载和管理服务。 相反,它使用易于理解和修改的简单配置文件
  •  Upstart 不像 System V 一样连续加载服务。这减少了系统引导时间
  •  Upstart 的采用了灵活的事件系统定制服务是如何在各种状态下处理
  •  Upstart 有更好的方式来处理崩溃的服务应该重生的方式
  •  没有必要保留一些冗余的符号链接,都指向同一个脚本
  •  Upstart 与 System V 的向后兼容/etc/init.d/rc脚本仍然运行管理本地系统 V 服务

Upstart 活动

Upstart 允许将与服务相关联多个事件 。 这种基于事件的架构允许 Upstart 灵活地处理服务管理。

每个事件都可以触发一个处理该事件的 shell 脚本。

Upstart 活动包括:

  •  开始
  •  开始
  •  停止
  •  停止

在这些事件之间,服务可以是在许多 ,像:

  •  等候
  •  预启动
  •  开始
  •  运行
  •  预停
  •  停止
  •  等等

Upstart 也可以对这些状态中的每一个采取行动,创建一个非常灵活的架构。

Upstart Init 序列

如 System V,也 Upstart 运行/etc/init.d/rc在启动脚本。 此脚本正常执行任何 System V init 脚本。

Upstart 也期待下/etc/init目录,并在每个服务配置文件执行 shell 命令。

Upstart 配置文件

Upstart 使用配置文件来控制服务。

Upstart 不使用系统 V 的方式使用 Bash 脚本。 相反,Upstart 使用服务配置文件与命名标准service_name .conf 。

该文件的纯文本内容不同的部分,称为 。 每节描述了服务的不同方面以及它应该如何运行。

不同的控制节为服务不同的事件,如预启动 , 启动 ,前期停止停止后 。

节本身包含 shell 命令。 因此,可以为每个服务的每个事件调用多个操作。

每个配置文件还指定了两件事:

  •  服务应该启动和停止的运行级别
  •  无论它是否崩溃服务应该重生

目录结构

Upstart 配置文件位于下/etc/init目录(不要与混淆/etc/init.d )。

Upstart 示例

让我们来看看 Upstart 如何再次处理 MySQL Server,这次有更多的背景知识。

第 1 步 – 登录到 Ubuntu Droplet

回到我们在第 1 部分中创建的 Ubuntu 14.04 Droplet。

使用 SSH 命令连接到服务器(Windows 用户可以使用像 PuTTy 这样的工具进行连接)。

ssh sammy@your_server_ip

第 2 步 – 查看 init 和 rc 目录

大多数 Upstart 的 config 文件在/etc/init目录中。 这是创建新服务时应使用的目录。

登录服务器后,执行以下命令:

sudo ls -l /etc/init/ | less

结果将显示大量的服务配置文件,一次一屏。 这些是在 Upstart 下本机运行的服务:

total 356
. . .
-rw-r--r-- 1 root root  297 Feb  9  2013 cron.conf
-rw-r--r-- 1 root root  489 Nov 11  2013 dbus.conf
-rw-r--r-- 1 root root  273 Nov 19  2010 dmesg.conf
. . .
-rw-r--r-- 1 root root 1770 Feb 19  2014 mysql.conf
-rw-r--r-- 1 root root 2493 Mar 20  2014 networking.conf

Q退出less 。

将其与系统中的本机 System V init 服务进行比较:

sudo ls -l /etc/rc3.d/* | less

将只有少数:

-rw-r--r-- 1 root root 677 Jun 14 23:31 /etc/rc3.d/README
lrwxrwxrwx 1 root root  15 Apr 17  2014 /etc/rc3.d/S20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root  24 Apr 17  2014 /etc/rc3.d/S20screen-cleanup -> ../init.d/screen-cleanup
lrwxrwxrwx 1 root root  19 Apr 17  2014 /etc/rc3.d/S70dns-clean -> ../init.d/dns-clean
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S70pppd-dns -> ../init.d/pppd-dns
lrwxrwxrwx 1 root root  26 Apr 17  2014 /etc/rc3.d/S99digitalocean -> ../init.d//rc.digitalocean
lrwxrwxrwx 1 root root  21 Apr 17  2014 /etc/rc3.d/S99grub-common -> ../init.d/grub-common
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S99ondemand -> ../init.d/ondemand
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S99rc.local -> ../init.d/rc.local

第 3 步 – 查看 Upstart 文件

我们已经看到了mysql.conf在本教程的第 1 部分文件。 所以,让我们打开另一个配置文件:一个为 cron 守护进程。

sudo nano /etc/init/cron.conf

如你所见,这是一个相当简单的配置文件的 cron 守护进程:

/etc/init/cron.conf
# cron - regular background program processing daemon
#
# cron is a standard UNIX program that runs user-specified programs at
# periodic scheduled times

description     "regular background program processing daemon"

start on runlevel [2345]
stop on runlevel [!2345]

expect fork
respawn

exec cron

最重要的领域要留意这里start on , stop onrespawn 。

start on指令告诉 Ubuntu 的启动crond当系统进入运行级别 2,3,4 或 5。2,图 3,和图 4 是多用户文本模式启用联网守护程序,和图 5 是多用户的图形模式。 该服务不运行在任何其他运行级别(如 0,1 或 6)。

fork指令告诉 Upstart 过程中应该从控制台分离并在后台运行。

接下来是respawn指令。 这告诉系统 cron 应该自动启动,如果它崩溃的任何原因。

退出编辑器,不进行任何更改。

cron 配置文件是一个相当小的配置文件。 MySQL 配置文件在结构上类似于 cron 配置文件; 它也有开始,停止和重生的节。 此外,它还有两个脚本块用于启动前和启动后事件。 这些代码块告诉系统当 mysqld 进程正在启动或已经启动时要执行什么。

有关使自己的 Upstart 文件实际的帮助,请参阅本教程的 Upstart 。

第 4 步 – 在引导时测试 MySQL 启动行为

我们知道我们的 Ubuntu 14.04 服务器上的 MySQL 实例默认设置为在启动时自动启动。 让我们看看如何禁用它。

在 Upstart,禁用服务依赖于文件的下存在/etc/init/称为service_name .override 。 该文件的内容应该是一个简单的单词: manual 。

要查看我们如何使用此文件来禁用 MySQL,请执行以下命令为 MySQL 创建此覆盖文件:

sudo nano /etc/init/mysql.override

添加这一行:

/etc/init/mysql.override
manual

保存更改。

接下来,重新启动服务器:

sudo reboot

服务器恢复在线后,请检查服务的状态

sudo initctl status mysql

输出应为:

mysql stop/waiting

这意味着 MySQL 没有启动。

检查start指令 MySQL 的服务配置文件中已经改变:

sudo cat /etc/init/mysql.conf | grep start\ on

它应该是相同的:

start on runlevel [2345]

这意味着,选中.conf在文件init目录是不希望看到,如果服务将在适当水平开始的唯一因素。 您还需要确保.override文件不存在。

要重新启用 MySQL,请删除覆盖文件并重新启动服务器:

sudo rm -f /etc/init/mysql.override
sudo reboot

一旦服务器重新启动,远程连接到它。

运行sudo initctl status mysql命令将显示该服务已自动启动。

第 5 步 – 测试崩溃崩溃的 MySQL 启动行为

默认情况下,MySQL 在崩溃后自动启动。

要停止 MySQL 的,请打开/etc/init/mysql.conf服务配置文件:

sudo nano /etc/init/mysql.conf

注释掉两个respawn指令。

/etc/init/mysql.conf
# respawn
# respawn limit 2 5

运行以下命令重新启动服务:

sudo initctl stop mysql
sudo initctl start mysql

我们明确地停止和启动服务,因为我们的测试表明initctl restartinitctl reload就不会在这里工作。

第二个启动服务的命令显示 PID 启动的 MySQL:

mysql start/running, process 1274

注意你的 MySQL 实例的 PID。 如果你崩溃mysql ,现在的过程,它不会自动来了。 删除进程 ID(将其替换为您自己的数字):

sudo kill -9 1274

现在检查其状态:

sudo initctl status mysql
mysql stop/waiting

尝试找到状态几次,在每个之间给一些时间。 在每种情况下,MySQL 仍然会停止。 这是发生因为该服务配置文件没有respawn的指令了。

1 份的教程的具有的一个更详细的解释respawn指令。

当你想要一个 Upstart 的服务上来重新启动后还是崩溃?

说你已经升级你的 Linux 内核或放最新的补丁。你不想要任何戏剧; 你只是服务器来了。 您可以通过禁用任何 Upstart 进程的自动启动来大大消除风险。

如果你的服务出现但仍然崩溃,你可以先停止它,然后改变它的重生行为。

systemd 简介

最新的 Linux init 守护进程是 systemd。 事实上,它不仅仅是一个 init 守护进程:systemd 是一个全新的框架,包含了现代 Linux 系统的许多组件。

它的作用之一是为 Linux 的系统和服务经理 。 在这种情况下,systemd 控制的一个东西是服务崩溃或机器重新启动时的行为。 你可以读到这里 systemd 的 systemctl 。

systemd 向后兼容 System V 命令和初始化脚本。 这意味着任何 System V 服务也将在 systemd 下运行。 这是可能的,因为大多数 Upstart 和 System V 管理命令已被修改为在 systemd 下工作。

事实上,如果我们运行ps -ef | grep systemd ps -ef | grep systemd在支持它的操作系统命令,我们将不会看到任何东西,因为systemd重命名自己init在启动时。 有一个/sbin/init文件,这是一个符号链接到/bin/systemd 。

systemd 配置文件:单元文件

在 systemd 的心脏是单元文件 。 每个单元文件表示系统资源。 systemd 和其他两个 init 方法之间的主要区别是,systemd 不仅负责服务守护程序,而且负责其他类型的资源(如套接字,设备操作系统路径,安装点,套接字等)的初始化。资源可以是这些。

在单元文件中跟踪有关资源的信息。

每个单元文件代表一个特定的系统资源,拥有的命名风格service name . unit type 。

因此,我们将有像文件dbus.service , sshd.sockethome.mount 。

正如我们将在后面看到,服务单元文件是简单的文本文件(如 Upstart.conf文件)具有声明语法。 这些文件很容易理解和修改。

目录结构

在基于 Red Hat 的系统(如 CentOS)中,单元文件位于两个位置。 主要位置是/lib/systemd/system/ 。

由系统管理员修改自定义创建单元文件或现有的单元文件将生活下/etc/systemd/system 。

如果具有相同名称的单元文件在两个位置存在,systemd 将使用下一个/etc 。 如果服务已启用在启动时或任何其他的目标/运行级别启动,一个符号链接将被该服务单元下的文件在适当的目录中创建/etc/systemd/system 。 在单元文件/etc/systemd/system实际上是符号链接的文件下同名/lib/systemd/system 。

初始序列:目标单位

一种特殊类型的单元文件是一个目标单位 。

一个目标单位的文件名是由 Stapling.target 。 目标单位与其他单位文件不同,因为它们不代表一个特定的资源。 相反,它们代表系统在任何时间的状态。

目标单元通过分组和启动应该是该状态的一部分的多个单元文件来做到这一点。 systemd 目标 ,因此可以松散相比系统 V 运行级别,尽管它们并不相同。

每个目标都有一个名称,而不是一个数字。 例如,我们已经multi-user.target ,而不是运行级别 3 或reboot.target,而不是运行级别 6。

当 Linux 服务器靴子说, multi-user.target ,它本质上使服务器到运行级别 2,3 或 4,这是多用户的文本模式与网络启用。

如何将服务器带到这个阶段是差异在哪里。 与 System V 不同,systemd 不会按顺序启动服务。 一路上,它可以检查其他服务或资源的存在,并决定其加载的顺序。 这使得服务可以并行加载。

目标单元和运行级别之间的另一个区别是,在 System V 中,Linux 系统只能存在一个运行级别。 您可以更改运行级别,但系统将仅存在于该新的运行级别。 与 systemd,目标单元可以包容的,这意味着当一个目标单元激活,它可以确保其他目标单元被加载为它的一部分。

例如,在 Linux 的系统,与图形用户界面靴将具有graphical.target激活,这反过来会自动确保multi-user.target被加载并激活为好。

(在系统 V 术语中,这将类似地具有同时激活运行级别 3 和 5)。

下表比较运行级别和目标:

运行级别(System V init) 目标单位(Systemd)
运行级 0 poweroff.target
运行级 1 resuce.target
运行级 2,3,4 multi-user.target
运行级 5 graphical.target
运行级 6 reboot.target

systemd default.target

default.target等同于默认的运行级别。

在 System V,我们在一个叫做文件中定义的默认运行级别inittab 。 在 systemd,该文件被替换default.target 。 默认的目标单元文件家住下/etc/systemd/system目录下。 这是一个符号链接在目标单位的一个文件/lib/systemd/system

当我们更改默认目标时,我们基本上重新创建该符号链接并更改系统的运行级别。

在系统 V inittab 文件还指定哪个目录的 Linux 将执行其启动脚本:它可以是任何RCñ.D目录。 在 systemd 中,默认目标单元确定在引导时加载哪些资源单元。

所有这些单元被激活,但不是全部并行或全部顺序。 如何资源单位负载可能依赖于其他资源的单位希望需要 。

systemd 依赖关系:需要

关于单元文件和目标单元的讨论的原因是突出显示 systemd 如何解决其守护进程之间的依赖。

正如我们之前看到的,Upstart 确保使用配置文件并行加载服务。 在系统 V 中,服务可以在特定运行级别开始,但也可以使其等待直到另一个服务或资源可用。 以类似的方式,可以使系统服务在一个或多个目标中加载,或者等待直到另一个服务或资源变为活动。

在 systemd, 需要另一个单位的单位将无法启动,直到所需的单元被加载并激活。 如果在第一个单元激活时所需单元由于某种原因而失效,则第一个单元也将停止。

如果你考虑它,这可以确保系统的稳定性。 因此,可以使需要存在特定目录的服务等待,直到该目录的安装点是活动的。 在另一方面, 希望其他单位不会强加这样的限制单位。 如果当主叫方活动时,所需单元停止,它不会停止。 一个例子是在图形目标模式下出现的非必要服务。

systemd 示例

现在是我们深入研究 MySQL 在 systemd 下的启动行为的时候了。

第 1 步 – 登录 CentOS Droplet

要了解所有这些概念以及它们如何与启用服务自动启动相关,让我们回到我们在第 1 部分中创建的 CentOS 7 Droplet。

使用 SSH 命令连接到服务器(Windows 用户可以使用像 PuTTy 这样的工具进行连接)。

ssh sammy@your_server_ip

第 2 步 – 查看 default.target 文件和依赖关系

这是一个长的路段,因为我们要遵循.target兔踪迹,据我们可以。 systemd 的启动顺序遵循一个长链的依赖关系。

defaul.target

default.target正常的服务器引导过程中哪些服务启动文件控制。

执行以下命令以列出默认目标单元文件:

sudo ls -l /etc/systemd/system/default.target

这将显示如下输出:

lrwxrwxrwx. 1 root root 37 Jul  8  2014 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target

正如我们所看到的,默认的目标实际上是一个符号链接下的多用户目标文件/lib/systemd/system/ 。 所以,该系统应该下引导multi-user.target ,这类似于运行级别 3。

multi-user.target.wants

接下来,执行下面的命令检查所有的服务multi-user.target文件 :

sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service

这应该显示这样的输出:

. . .
lrwxrwxrwx. 1 root root  37 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/crond.service -> /usr/lib/systemd/system/crond.service
. . .
lrwxrwxrwx  1 root root  38 Jul 31 22:02 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service
lrwxrwxrwx. 1 root root  46 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root  39 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/postfix.service -> /usr/lib/systemd/system/postfix.service
lrwxrwxrwx. 1 root root  39 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root  36 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service
. . .

我们可以看到,这些都是符号链接文件,指回单位实际文件下的/lib/systemd/system/ 。 我们还可以看到, mysqld.service是一部分multi-user.target 。

如果您执行此命令过滤输出,可以找到相同的信息:

sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql
mysqld.service

除了multi-user.target ,有不同类型的像目标system-update.targetbasic.target 。

要查看我们的多用户目标取决于什么目标,请执行以下命令:

sudo systemctl show --property "Requires" multi-user.target | fmt -10
Requires=basic.target

于是,开始在系统multi-user.target模式, basic.target将必须先加载。

basic.target

看看其他目标basic.target依赖,执行以下命令:

sudo systemctl show --property "Requires" basic.target | fmt -10

输出将是:

Requires=sysinit.target

sysinit.target

展望递归,我们可以看到,如果有任何需要的单位sysinit.target 。 没有。 However, we can see what services are wanted by sysinit.target :

sudo systemctl show --property "Wants" sysinit.target | fmt -10

This will show a number of services wanted by sysinit.

Wants=local-fs.target
swap.target
cryptsetup.target
systemd-udevd.service
systemd-update-utmp.service
systemd-journal-flush.service
plymouth-read-write.service
. . .

As you can see, the system does not stay in one target only. It loads services in a dependent fashion as it transitions between targets.

Step 3 — Looking at a Unit File

Going a step further now, let’s look inside a service unit file. We saw the MySQL service unit file in Part 1 of this tutorial, and we will use it again shortly, but for now let’s open another service unit file, the one for sshd:

sudo nano /etc/systemd/system/multi-user.target.wants/sshd.service

它看起来像这样:

[Unit]
Description=OpenSSH server daemon
After=syslog.target network.target auditd.service

[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStartPre=/usr/sbin/sshd-keygen
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

Just like an Upstart daemon config file, this service unit file is clean and easy to understand.

The first important bit to understand is the After clause. This says the SSHD service needs to load after the system and network targets and the audit logging service are loaded.

The file also shows the service is wanted by the multi-user.target , which means the target will load this service, but it won’t shut down or crash if sshd fails.

Since multi-user.target is the default target, sshd daemon is supposed to start at boot time.

Exit the editor.

Step 4 — Testing MySQL Startup Behavior at Boot

In Part 1 of the tutorial, we left the MySQL service enabled and running. Let’s see how to change that.

In the last section, we ran a command to confirm that mysqld.service is wanted by multi-user.target . When we listed the contents of the /etc/systemd/system/multi-user.target.wants/ directory, we saw a symbolic link pointing back to the original service unit under /usr/lib/systemd/system/ .

Run the following command to disable the service so it does not auto-start at boot time:

sudo systemctl disable mysqld.service

Now, run this command to check if MySQL is still wanted by multi-user.target :

sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql

Nothing will be returned. Run the command below to check if the symbolic link still exists:

sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*

The link doesn’t exist:

ls: cannot access /etc/systemd/system/multi-user.target.wants/mysql*: No such file or directory

If you’d like, try rebooting the server. MySQL should not come up.

Now reenable the service:

sudo systemctl enable mysqld.service

The link will come back:

sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
lrwxrwxrwx 1 root root 38 Aug  1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service

(If you rebooted before, you should start MySQL again.)

As you can see, enabling or disabling a systemd service creates or removes the symbolic link from the default target’s wants directory.

Step 5 — Testing MySQL Startup Behavior on Crash

MySQL will currently come up automatically after a crash. Let’s see how to disable that.

Open the MySQL service unit file in an editor:

sudo nano /etc/systemd/system/multi-user.target.wants/mysqld.service

After the header information, the contents of the file looks like this:

/etc/systemd/system/multi-user.target.wants/mysqld.service
[Unit]
Description=MySQL Community Server
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target
Alias=mysql.service

[Service]
User=mysql
Group=mysql

# Execute pre and post scripts as root
PermissionsStartOnly=true

# Needed to create system tables etc.
ExecStartPre=/usr/bin/mysql-systemd-start pre

# Start main service
ExecStart=/usr/bin/mysqld_safe

# Don't signal startup success before a ping works
ExecStartPost=/usr/bin/mysql-systemd-start post

# Give up if ping don't get an answer
TimeoutSec=600

Restart=always
PrivateTmp=false

As we saw in Part 1, the value of the Restart parameter is set to always (for sshd, this was set to on-failure only). This means the MySQL service will restart for clean or unclean exit codes or timeouts.

The man page for systemd service shows the following table for Restart parameters:

Restart settings/Exit causes 没有 总是 on-success on-failure on-abnormal on-abort on-watchdog
Clean exit code or signal   X X        
Unclean exit code   X   X      
Unclean signal   X   X X X  
暂停   X   X X    
Watchdog   X   X X   X

In a systemd service unit file, the two parameters – Restart and RestartSec – control crash behaviour. The first parameter specifies when the service should restart, and the second parameter defines how long it should wait before restarting.

Comment out the Restart directive, save the file, and exit the editor. This will disable the restart behavior.

/etc/systemd/system/multi-user.target.wants/mysqld.service
# Restart=always

Next, reload the systemd daemon, followed by a restart of the mysqld service:

sudo systemctl daemon-reload
sudo systemctl restart mysqld.service

Next, find the Main PID of the service by running this command:

sudo systemctl status mysqld.service
. . .
Main PID: 11217 (mysqld_safe)

Using the kill -9 command, kill the main PID, using your own number.

sudo kill -9 11217

Running the sudo systemctl status mysqld.service again will show that the service has failed:

sudo systemctl status mysqld.service
mysqld.service - MySQL Community Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
   Active: failed (Result: signal) since Sun 2015-06-21 02:28:17 EDT; 1min 33s ago
  Process: 2566 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)
  Process: 2565 ExecStart=/usr/bin/mysqld_safe (code=killed, signal=KILL)
  Process: 2554 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 2565 (code=killed, signal=KILL)

Jun 21 02:20:09 test-centos7 systemd[1]: Starting MySQL Community Server...
Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Logging to '/var/log/mysqld.log'.
Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
Jun 21 02:20:10 test-centos7 systemd[1]: Started MySQL Community Server.
Jun 21 02:28:16 test-centos7 systemd[1]: mysqld.service: main process exited, code=killed, status=9/KILL
Jun 21 02:28:17 test-centos7 systemd[1]: Unit mysqld.service entered failed state.

Try to find the service status a few times, and each time the service will be shown as failed.

So, we have emulated a crash where the service has stopped and hasn’t come back. This is because we have instructed systemd not to restart the service.

Now, if you edit the mysqld.service unit file again, uncomment the Restart parameter, save it, reload the systemctl daemon, and finally start the service, it should be back to what it was before.

This is how a native systemd service can be configured to auto-start after crash. All we have to do is to add an extra directive for Restart (and optionally RestartSec ) under the [Service] section of the service unit file.

结论

So this is how Linux handles service startup. We have seen how System V, Upstart, and systemd init processes work and how they relate to auto-starting a service after a reboot or crash.

The declarative syntax of Upstart config files or systemd unit files is an improvement over the arcane System V init scripts.

As you work with your own Linux environment, check your distribution’s version and see what init daemon it supports.

It will be worthwhile to think about where would you want to enable a service and where would you want to disable it. In most cases, you don’t have to change anything for third-party applications or native Linux daemons. It’s only when you create your own service-based applications that you have to think about their startup and respawn behavior.

猜你喜欢

转载自www.cnblogs.com/DataArt/p/10173821.html