频道栏目
首页 > 资讯 > Linux > 正文

如何配置Linux服务,确保崩溃或重启后自动加以运行——第一部分:应用实例

17-03-23        来源:[db:作者]  
收藏   我要投稿

如何配置Linux服务,确保崩溃或重启后自动加以运行——第一部分:应用实例。

本教程将讲解如何配置系统服务,旨在遭遇崩溃或服务器重启后能够自动加以运行。

本示例使用MySQL,但大家也可利用同样的方式重新运行服务器上的其它服务,例如Nginx或Apache等。

本教程中我们将涵盖三种最为常见的init系统,因此请选择适用于您具体发行版的内容。(很多发行版提供多种选项,或者允许用户安装其它init系统。)

System V为较早的init系统:

Debian 6及更早版本 Ubuntu 9.04及更早版本 CentOS 5及更早版本

Upstart:

Ubuntu 9.10到Ubuntu 14.10,包括Ubuntu 14.04 CentOS 6

systemd为各最新发行版中的init系统:

Debian 7与Debian 8 Ubuntu 15.04及更新版本 CentOS 7

大家也可参阅本系列文章的第二篇查看相关参考资料。

背景介绍

运行中的Linux或Unix系统始终拥有大量后台进程处于执行状态。这些进程——或者可称为服务守护程序——可能属于操作系统的原生组件,或者作为应用程序的一部分存在。

操作系统服务示例:

sshd守护程序,用于远程连接 cupsd守护程序,用于控制打印

应用程序守护程序示例:

httpd/apache2属于Web服务器服务 mongod属于数据库守护程序

这些服务需要持续运行以支持我们的网站、邮件、数据库及其它应用。

作为管理员,我们需要确保Linux服务:

持续运行且不存在故障 在系统重启或崩溃时能够自动运行

但有时候这些服务仍会停止,并导致网站或应用不再可用。

本文的目标在于以自动化方式重新启动并运行。

我们可以变更服务管理守护程序的处理方式确保Linux服务拥有自我修复能力,而此类守护程序正是之前所提到的init系统。

不同Linux发行版往往配备不同的服务管理守护程序,我们之前已经提到了各常见发行版所使用的默认init系统。

更多细节可参阅本系列文章的第二部分。在这部分中,我们将首先了解Linux系统中所存在的四项基本runlevel:

0 - Runlevel 0代表系统停机 1 - Runlevel 1代表单用户援助模式 5 - Runlevel 5代表多用户、网络可用、图形模式 6 - Runlevel 6代表系统重启

总体而言,runlevel 2、3与4代表着Linux处于多用户、网络启用、文本模式。

当我们将某项服务设为自动启动,即相当于将其添加到了一种runlevel当中。

目标

在本系列教程中,我们将了解如何配置一项Linux服务,从而确保其在系统重启或崩溃后能够再次自动运行。

在第一部分教程内,我们将了解如何使用三种不同的init(即初始化)模式:

System V init (亦被称为经典init) Upstart systemd

先决条件

要完成本教程,大家需要创建数个DigitalOcean Droplets(或者自己的Linux服务器),其各自需要至少1 GB内存。关于Droplet的具体创建方法,大家可以参阅此处

我们将在示例中使用多种不同发行版。

Debian 6 x64(这款较早版本的OS用于演示System V init系统) Ubuntu 14.04 x64 (演示Upstart) CentOS 7 x64 (演示systemd) 大家还需要在每台服务器上设置一个sudo用户。欲了解更多与sudo权限机制相关的信息,可参阅启用sudo访问相关教程

最后提醒大家,请不要将本教程中的任何命令、查询或者配置应用于生产服务器当中。

利用System V实现服务自动启动

首先来看System V init。

Debian 6及更早版本 Ubuntu 9.04及更早版本 CentOS 5及更早版本

在System V中,大家安装的大部分标准应用——例如Nginx或MySQL——都会在重启后默认自动运行,但崩溃后其无法自动运行。这些应用将在/etc/init.d文件中拥有其init脚本。

对于定制化应用,大家需要创建自己的init脚本并手动启用其自动运行机制。

本文不会介绍如何创建init脚本,但大家可以参考现有示例了解其内容设定方式。System V利用Bash实现init脚本。

System V的自动启动清单

配置清单

确保/etc/init.d/service当中存在该服务的功能性Bash init脚本

使用update-rc.d命令以启用该服务(在CentOS系统中,命令为chkconfig):

sudo update-rc.d service enable

此命令会在/etc/rc2.d中创建一条symlink,如下所示(不要手动进行创建):

lrwxrwxrwx 1 root root  15 Jul 31 07:09 S02mysql -> ../init.d/service

请注意,我们应当看到/etc/rc3.d到/etc/rc5.d这几个目录,我们将在后续的runlevel部分对具体数字进行讲解。

在/etc/inittab文件末尾为该服务添加respawn行。示例如下:

/etc/inittab

id:2345:respawn:/bin/sh /path/to/application/startup

停止该服务,而后重新启动:

-   sudo service service stop

-   sudo service service start

重启该服务器。

-   sudo reboot

测试

要测试上述设置是否有效,大家可以:

重启服务器并检查服务是否正在运行

搜索进程数字:

-   ps -ef | grep service

关闭该进程:

-   sudo kill -9 process_number

等待五分钟,而后检查该服务是否正在运行。

第一步——接入Debian 6 Droplet

现在我们将利用MySQL运行实例。首先在DigitalOcean控制面板中创建一个内存为1 GB的Debian 6.0 x64 Droplet。

Droplet初始化完成后,使用SSH以接入该服务器(Windows用户可以利用PuTTY等工具实现接入)。

- ssh sammy@your_server_ip

在以下操作中,我们假定大家的账户已经拥有sudo权限。

第二步——安装MySQL

我们将利用MySQL作为测试对象。执行以下命令以安装MySQL Server:

- sudo apt-get install mysql-server -y

下图所示为新的root密码输入界面:

再输入一次密码:

按下回车以确认。

MySQL安装完成后,运行以下命令以保护安装结果:

- mysql_secure_installation

此次我们需要输入当前root密码。按下N以继续使用原有密码。而后按下Y以移除匿名用户、禁用远程root登录并移除测试数据库。最后,按下Y以重新载入权限表。

到这里安装工作就完成了。

执行以下命令以检查该服务是否正在运行:

- service mysql status

输出结果将显示为数行信息,其中一行显示了MySQL服务的运行时间:

Output

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

. . .

Uptime:         4 days 18 hours 58 min 27 sec

Threads: 1  Questions: 18  Slow queries: 0  Opens: 15  Flush tables: 1  Open tables: 8  Queries per second avg: 0.0.

第三步——配置MySQL确保在重启后自动运行

在默认情况下,MySQL会在重启后自动运行。

大家可以在/etc/rc2.d目录中的MySQL init脚本内查看到这条symlink。请注意,请不要手动创建这些symlink,使用update-rc.d命令以启用及禁用这些服务。

- ls -l /etc/rc2.d

Output

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

只要对应的默认runlevel目录下仍有S脚本存在,则init就会在服务器启动后自动运行该服务。

现在我们需要进行验证。重启设备:

- sudo reboot

当服务器再次上线,利用SSH进行接入。

再次运行service mysql status命令,结果显示其正在运行,意味着我们的实验已经获得成功。

不过在某些情况下,我们需要手动配置部分服务才能实现自动运行。在Debian系统中,使用update-rc.d命令以添加或移除需要自动运行的服务。

下面禁用MySQL服务,而后了解如何重新启动其自动运行机制。使用以下命令禁用MySQL:

- sudo update-rc.d mysql disable

为了进行测试,再次重启服务器。

- sudo reboot

通过SSH接入服务器。

使用MySQL客户端工具接入MySQL:

- mysql -u root -p

这时获得的信息如下:

Output

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

重新启用该服务:

- sudo update-rc.d mysql enable

输出结果变为:

Output

update-rc.d: using dependency based boot sequencing

如果大家使用的是CentOS系统配合System V,则将update-rc.d命令替换为chkconfig。

请注意,启动时自动执行并不代表某项服务能够在被关闭后自行开启。要启动MySQL,请使用以下命令:

- sudo service mysql start

第四步——配置MySQL以实现崩溃后自动运行

现在我们开始考虑崩溃后的情况。在System V中,崩溃后重启并非默认选项。

我们将突然关闭进程以模拟崩溃情况。利用以下命令找到其进程ID:

- ps -ef | grep mysql

输出结果如下:

Output

root      1167     1  0 07:21 pts/0    00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql     1292  1167  0 07:21 pts/0    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      1293  1167  0 07:21 pts/0    00:00:00 logger -t mysqld -p daemon.error
root      1384  1123  0 07:21 pts/0    00:00:00 grep mysql

MySQL的主进程为mysqld_safe与mysqld。其中mysqld_safe为mysqld的父进程。

在本示例中,我们可以看到其进程ID分别为1167与1292。其进程数字以红色进行高亮显示。

下面使用kill -9命令模拟崩溃情况:

- sudo kill -9 1167
- sudo kill -9 1292

检查服务状态:

- sudo service mysql status

输出结果显示该服务已经停止:

Output

MySQL is stopped..

现在我们的服务已经崩溃。接下来考虑如何以自动方式使其重新运行——具体办法为编辑/etc/inittab文件。

我们将在第二部分教程内详尽探讨/etc/inittab文件,现在我们只需要知晓其为System V init在启动时读取的第一个文件。

事实上,/etc/inittab负责决定某一进程在崩溃后该如何反应。对于某些进程,其需要重新启动服务——MySQL自然也属于这一类。因此首先将其拷贝出来:

- sudo cp /etc/inittab /etc/inittab.orig

请注意:在编辑/etc/inittab文件时需要万分小心。如果大家在命令中出现错误或者删除了现有配置,那么系统将无法在重启后正常运行。

在文本编辑器中打开/etc/inittab:

- sudo nano /etc/inittab

在文件末尾添加以下行:

/etc/inittab

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

其含义是,我们在/etc/inittab文件内添加了命令,旨在恢复崩溃了的mysqld_safe进程。其中包含四个字段,彼此之间以冒号分隔。

ms: 前两个字母负责指定目标进程的ID。 2345: 第二字段负责指定其应用的runlevel。在本示例中,其runlevel为2、3、4、5。 respawn: 第三字段指定具体操作(即恢复该服务)。 /bin/sh /usr/bin/mysqld_safe: 最后,第四字段为目标进程(即命令的执行对象)。

完成后保存并退出。

再次启动该服务:

- sudo service mysql start

重启服务器以应用变更:

- sudo reboot

现在再次搜索进程ID,关闭进程,检查运行状态,等待5分钟后执行以下命令:

- sudo service mysql status

现在可以看到,MySQL已经在崩溃后自动重启。

成功了!MySQL已经能够在系统崩溃与重启这两种情况下自行恢复运转。

利用Upstart实现服务自动运行

Upstart属于另一种init方法,其最初出现在Ubuntu 6当中。目前其在Ubuntu 9.10、RHEL 6以及谷歌Chrome OS等系统中作为默认选项。

Ubuntu 9.10到Ubuntu 14.10, 包括Ubuntu 14.04 CentOS 6

Upstart在处理系统服务方面比System V表现得更好,而且也易于掌握。不过我们在这里不会深入探讨,感兴趣的朋友可以参阅Upstart使用教程

Upstart利用配置文件实现服务控制。这些文件位于/etc/init目录,采用纯文本内容并以易于阅读的方式存在于stanzas区段之内。每条stanza负责描述服务的一个方面以及执行方式。

在默认情况下,Nginx或MySQL等标准应用都能够在重启或崩溃后自动恢复运行,因为其init脚本已经直接存在于/etc/init当中。

对于其它定制化应用,大家需要进行手动设置。要了解更多与定制Upstart脚本相关的内容,请参阅之前提到的Upstart使用教程

Upstart的自动运行列表

配置列表

确保服务在/etc/init/service.conf处拥有一个功能性Upstart init脚本

/etc/init/service.conf文件应当包含诸如start on runlevel [2345]的一行,从而在重启后实现自动恢复 /etc/init/service.conf文件应当包含respawn行以确保服务在崩溃后能够自动恢复

确保此处不存在目标服务的override文件:

/etc/init/service.override

(此文件只应在我们自己或者其他管理员此前创建过时存在)

停止后重新启动服务:

-   sudo initctl stop service
-   sudo initctl start service

重启服务器:

-   sudo reboot

测试

要测试上述设置是否有效,大家可以:

重启服务器并检查服务是否正在运行

搜索进程数字:

-   ps -ef | grep service

关闭该进程:

-   sudo kill -9 process_number

等待数秒并验证服务是否已经重新运行。

第一步——接入Ubuntu 14.04 Droplet

这里我们使用Ubuntu 14.04服务器,运行MySQL以演示Upstart。

利用Ubuntu 14.04 x64作为基础镜像,创建一套内存为1 GB的Droplet。

利用SSH接入该服务器:

- ssh sammy@your_server_ip

在以下操作中,我们假定大家的账户拥有sudo权限。

第二步——安装MySQL

下面安装MySQL。执行以下命令以更新软件包列表:

- sudo apt-get update

安装MySQL Server:

- sudo apt-get install mysql-server -y

为MySQL创建新的root密码并确定。

安装完成后,运行mysql_secure_installation命令:

- mysql_secure_installation

其余部分与此前Debian中的安装流程一致。

第三步——配置MySQL以实现重启后服务运行

默认情况下,MySQL会在重启后自动恢复运行。大家可以查看其配置,并将方法应用于其它服务。

首先检查MySQL进程是否正在运行:

- sudo initctl status mysql

结果如下:

Output

mysql start/running, process 2553

重启服务器:

- sudo reboot

在服务器重新上线后,使用SSH重新接入。

检查MySQL状态:

- sudo initctl status mysql

可以看到,MySQL已经自动启动。

请注意,对于其它应用守护程序,我们需要在/etc/init/目录内手动创建Upstart文件以实现自动启动。

那么,要如何告知Upstart在服务器重启后自动运行MySQL?

首先利用文本编辑器打开MySQL的Upstart init文件/etc/init/mysql.conf:

- sudo nano /etc/init/mysql.conf

Upstart文件与我们之前提到的shell脚本完全不同。

MySQL的init配置文件中将包含用于实现pre-start与post-start事件的脚本块。这些代码片段负责告知Upstart系统在mysqld进程正在启动或者已经启动时应执行哪些操作。

下面来看文件的前十行:

/etc/init/mysql.conf

...
description     "MySQL Server"
author          "Mario Limonciello <superm1@ubuntu.com>"

start on runlevel [2345]
stop on starting rc RUNLEVEL=[016]

respawn
respawn limit 2 5

可以看到,MySQL应该以runlevel 2、3、4、5启动,而非runlevel 0、1与6。

在这里我们可以对Upstart守护程序进行服务启动定义。在这里,我们直接使用服务配置文件即可。

其中respawn指令负责在崩溃后重新启动该服务,我们将在下一节中进行详细说明。

第四步——配置MySQL确保崩溃后自动启用服务

现在打开/etc/init/mysql.conf文件。

其中respawn命令的作用非常明确:MySQL会在崩溃后自动恢复。

接下来的指令则非常有趣:respawn limit指令限制了Linux尝试恢复崩溃服务的次数与尝试之间的相隔秒数。在本示例中,(2)为尝试次数,(5)为间隔秒数。如果服务无法在阈值之内顺利完成重启,则将一直处于停止状态。

现在,退出文本编辑器。

正如之前所见,默认情况下MySQL已经能够在崩溃后自动重启。

下面检查该服务的PID以进行测试:

- sudo initctl status mysql

重启后的新PID如下:

Output

mysql start/running, process 961

请注意这里的进程ID。下面利用kill -9命令将该进程关闭:

- sudo kill -9 961

再次检查MySQL状态,其应该再次运行并使用新的PID:

- sudo initctl status mysql

输出结果如下:

Output

mysql start/running, process 1552

如果大家愿意,可以多次重复上述操作:

之所以MySQL能够始终在线,是因为mysql.conf文件中的respawn命令。

/etc/init/mysql.conf

respawn

再次强调,MySQL属于默认自动恢复对象,但其它应用则需要大家修改其配置以实现同样的效果。

利用systemd实现服务自动恢复

systemd是一款Linux平台上的系统与服务管理器,且已经成为大多数新型Linux发行版的默认初始化守护程序。

Debian 7与Debian 8 Ubuntu 15.04 CentOS 7

systemd能够向下兼容System V命令与初始化脚本。

利用systemd,大多数安装的标准应用都能够在重启及崩溃后自动实现恢复。这些应用在/etc/systemd/system 当中拥有自己的init脚本。

对于定制化应用,大家需要创建自己的init脚本并借此实现服务恢复。关于这部分内容,请参阅systemd教程

systemd的自动启动列表

配置列表

确保该服务在/etc/systemd/system/multi-user.target.wants/service.service当中拥有一条功能性systemd init脚本。

使用systemctl命令以启动该服务:

-   sudo systemctl enable service.service

以上命令会创建一条指向/etc/systemd/system/multi-user.target.wants/的symlink,内容如下:

lrwxrwxrwx 1 root root 38 Aug  1 04:43 /etc/systemd/system/multi-user.target.wants/service.service -> /usr/lib/systemd/system/service.service

意味着服务将在重启后自动恢复。

/etc/systemd/system/multi-user.target.wants/service.service文件中应当包含Restart=always行,其位于[Service]区段之下,负责在崩溃后重新恢复服务:

加载systemd守护程序,而后重启该服务:

-   sudo systemctl daemon-reload

-   sudo systemctl restart service.service

测试

下面测试实际效果:

重启服务器后检查服务是否正在运行:

-   sudo reboot

搜索其进程号:

-   ps -ef | grep service

关闭该进程:

-   sudo kill -9 process_number

数秒之后,服务即可重新上线。

第一步——接入CentOS 7 Droplet

在本示例中,我们使用CentOS 7与MySQL以说明如何配置systemd服务。

首先创建一个1 GB内存的Droplet,并选择CentOS 7 x64作为其基础镜像。

使用SSH接入该服务器。

- ssh sammy@your_server_ip

这里我们假设大家的账户拥有sudo权限。

第二步——安装MySQL

运行以下命令以下载并安装MySQL Community server repo:

- sudo wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

- sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm

安装MySQL server:

- sudo yum install mysql-server -y

安装完成后,启动mysqld服务。

(请注意,在Debian与Ubuntu中的MySQL安装流程有所区别。在Debian中,安装完成后MySQL会自动启动。)

另外,我们使用systemctl命令来控制该服务:

- sudo systemctl start mysqld

接下来运行mysql_secure_installation命令。

- mysql_secure_installation

在这里MySQL root密码为空,大家可以根据需要创建一条新密码。其余流程部分与之前提到的Debian或Ubuntu一致。

第三步——配置MySQL以实现重启后自动恢复

默认情况下,MySQL会在重启后自动恢复运行。为了了解其实现原理,我们首先检查mysqld守护程序的具体配置。执行以下命令:

- sudo systemctl is-enabled mysqld.service

结果如下:

Output

enabled

重启设备:

- sudo reboot

服务器重新上线后,利用SSH进行接入。

执行以下命令检查服务状态:

- sudo systemctl status mysqld.service

输出结果如下:

Output

mysqld.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
Active: active (running) since Fri 2015-07-31 21:58:03 EDT; 1min 52s ago
Process: 662 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)
Process: 625 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 661 (mysqld_safe)
...

运行以下命令禁用该服务:

- sudo systemctl disable mysqld.service

这时服务并不会停止,但会被禁用。从输出结果中可以看到,symlink已经被删除了:

Output

rm '/etc/systemd/system/multi-user.target.wants/mysqld.service'
rm '/etc/systemd/system/mysql.service'

大家也可以重复以上过程,查看MySQL server是否会恢复运行。

或者再次执行systemctl is-enabled,结果如下:

- sudo systemctl is-enabled mysqld.service

Output

disabled

再次启用该服务:

- sudo systemctl enable mysqld.service

输出结果显示,symlink已经再次启用:

Output

ln -s '/usr/lib/systemd/system/mysqld.service' '/etc/systemd/system/mysql.service'
ln -s '/usr/lib/systemd/system/mysqld.service' '/etc/systemd/system/multi-user.target.wants/mysqld.service'

这意味着服务器重启后,服务将能够自动恢复。

第四步——配置MySQL确保崩溃后服务自动恢复

现在看看如何配置MySQL以确保崩溃后自动恢复。

首先打开mysqld.service unit文件(请记住,systemd服务使用unit文件以实现配置):

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

在文件末尾可以看到一条重启指令:

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

[Unit]
...

[Install]
...

[Service]
...
...
Restart=always
...

这里Restart参数被设定为always,意味着MySQL服务将在完全或不完全退出或者超时后始终自动重启。

这就是systemd中的自动重启定义方式。

与Upstart中的respawn指令类似,Restart参数负责定义服务在崩溃后执行何种操作。

并非所有systemd服务都在默认条件下启用自动恢复,不过大家可以在对应服务的unit文件内[Service]区段下添加额外指令以实现这一效果。

为了模拟崩溃情况,我们退出编辑器并检查MySQL进程ID:

- sudo systemctl status mysqld.service

Output

mysqld.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
Active: active (running) since Fri 2015-07-31 21:58:03 EDT; 1h 7min ago
Main PID: 661 (mysqld_safe)
...

在本示例中,主PID为661,大家需要将其替换为自己的实际PID:

- sudo kill -9 661

检查服务状态:

- sudo systemctl status mysqld.service

输出结果如下:

Output

mysqld.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
Active: active (running) since Fri 2015-07-31 23:06:38 EDT; 1min 8s ago
Process: 11218 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)
Process: 11207 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 11217 (mysqld_safe)
...
...

可以看到,服务能够在崩溃后自动实现恢复。

相关TAG标签
上一篇:Java设计模式 单例模式
下一篇:HbaseRESTFulAPI速查表
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站