如何将Linux服务配置为在崩溃或重启后自动启动-第2部分:参考

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。

介绍

在本教程中,您将使用 systemd 将 MySQL 配置为在重启或崩溃后自动重启。

这是两部分系列的后半部分。 第一部分 涵盖了一般的 Linux 服务管理概念,例如 init 守护进程和运行级别。 它以 systemd 中的服务管理演示结束。 在这里,您将检查 targetswantsrequiresunit 文件。 这一部分,第二部分,提供了一个使用MySQL数据库的实际例子。

先决条件

要完成本教程,您需要:

使用 systemd 配置 MySQL 以在引导后自动启动

安装 MySQL 后,检查服务的状态:

sudo systemctl status mysqld.service

输出应显示服务正在运行,但守护程序已禁用:

Output mysqld.service - MySQL 8.0 database server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; disabled; vendor preset: disabled)
    Active: active (running) since Thu 2020-12-24 23:48:56 UTC; 1h 6min ago
   Process: 30423 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
   Process: 30294 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)
   Process: 30270 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
 Main PID: 30378 (mysqld)
  Status: "Server is operational"
   Tasks: 40 (limit: 4763)
...

如果该服务已启用,请将其禁用。 在进行更改之前,我们希望首先探索禁用的行为:

sudo systemctl disable mysqld.service

接下来,运行此命令以检查 multi-user.target 是否需要 MySQL:

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

什么都不会回来。 现在检查符号链接是否存在:

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

出现一条消息,指出符号链接文件不存在:

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

现在,如果您愿意,重新启动服务器并检查 MySQL 服务。 它应该 而不是 正在运行。

无论您是否重新启动,现在重新启用 MySQL 服务:

sudo systemctl enable mysqld.service

这一次,系统会在/etc/systemd/system/multi-user.target.wants/下创建一个符号链接:

OutputCreated symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.

再次运行 ls 命令以确认这一点:

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

您将收到如下输出:

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

启用或禁用 systemd 服务会在默认目标的想要目录中创建或删除符号链接。

如果您愿意,请再次重新启动 Droplet,当它重新联机时,运行 ps -ef 命令检查服务状态。

ps -ef | grep mysql

如果 MySQL 正在运行,此命令将提供有关 MySQL 的信息:

[secondary_label Output]\
mysql        851       1  2 04:26 ?        00:00:02 /usr/libexec/mysqld --basedir=/usr

您现在已将 MySQL 配置为在重新启动后重新启动。 接下来,您将考虑崩溃。

使用 systemd 配置 MySQL 以在崩溃后自动启动

作为一个现代应用程序,MySQL 已经配置为在崩溃后自动启动。 让我们看看如何禁用它。

在编辑器中打开 MySQL 服务单元文件:

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

在头信息之后,文件的内容如下所示:

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

[Unit]

Description=MySQL 8.0 database server
After=syslog.target
After=network.target

[Service]

Type=notify
User=mysql
Group=mysql

ExecStartPre=/usr/libexec/mysql-check-socke
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
`# Note: we set --basedir to prevent probes that might trigger SELinux alarms,`
`# per bug #547485`
ExecStart=/usr/libexec/mysqld --basedir=/usr
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop

`# Give a reasonable amount of time for the server to start up/shut down`

TimeoutSec=300

`# Place temp files in a secure directory, not /tmp`

PrivateTmp=true

Restart=on-failure

RestartPreventExitStatus=1

`# Sets open_files_limit`

LimitNOFILE = 10000

`# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.`

Environment=MYSQLD_PARENT_PID=1

[Install]

WantedBy=multi-user.target

如您所见,Restart 参数的值设置为 on-failure。 这意味着 MySQL 服务将因不干净的退出代码或超时而重新启动。

systemd service 手册页显示了下表中的重启参数:

重启设置/退出原因 总是 成功 失败时 异常 中止 看门狗
清除退出代码或信号 X X
不干净的退出代码 X X
不干净的信号 X X X X
超时 X X X
看门狗 X X X X

在 systemd 服务单元文件中,两个参数 - RestartRestartSec - 控制崩溃行为。 第一个参数指定服务应该何时重新启动,第二个参数定义它应该在重新启动之前等待多长时间。

要测试崩溃行为,请使用 kill -9 信号停止 MySQL 进程。 在我们的例子中,主 PID 是 851; 用您自己的 PID 替换:

ps -ef | grep mysql

sudo kill -9 851

等待几秒钟,然后检查状态:

sudo systemctl status mysqld.service

输出将显示 MySQL 已使用新的 PID 重新启动(在我们的例子中,新的进程 ID 是 1513):

Output  mysqld.service - MySQL 8.0 database server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2020-12-25 04:47:48 UTC; 55s ago
  Process: 1420 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
  Process: 1559 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
  Process: 1476 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)Process: 1451 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
 Main PID: 1513 (mysqld)
   Status: "Server is operational"
...

接下来,重新打开单元文件:

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

注释掉 MySQL 守护进程单元文件中的 Restart 指令并保存。 这将禁用重启行为:

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

`# Restart=on-failure`

在此之后,重新加载 systemd 守护进程,然后重新启动 mysqld 服务:

sudo systemctl daemon-reload
sudo systemctl restart mysqld.service

您可以通过运行以下命令找到服务的主 PID:

sudo systemctl status mysqld.service
Output. . .
Main PID: 1895 (mysqld)

使用 kill -9 命令,在您的环境中终止 MySQL PID 的主 PID(我们在测试环境中使用 PID)。

sudo kill -9 1895

检查 MySQL 的状态:

sudo systemctl status mysqld.service

它将显示服务失败:

Outputmysqld.service - MySQL 8.0 database server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: **failed** (Result: signal) since Fri 2020-12-25 05:07:22 UTC; 1min 14s ago
  Process: 1976 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
  Process: 1940 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
  Process: 1895 ExecStart=/usr/libexec/mysqld --basedir=/usr (code=killed, signal=KILL)
  Process: 1858 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS
  Process: 1833 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
  Main PID: 1895 (code=**killed**, signal=KILL)
   ...

尝试多次查找服务状态。 每次服务将显示为 failed

因此,我们模拟了服务已停止且未返回的崩溃。 这是因为我们已指示 systemd 在不正常停止后不要重新启动服务。 如果编辑mysqld.service单元文件取消Restart参数的注释,保存,重新加载systemctl守护进程,最后重启服务,即可恢复正常功能。

这是您如何配置本地 systemd 服务以在崩溃后自动启动的方法。 您所要做的就是在服务单元文件的 [Service] 部分下为 Restart(以及可选的 RestartSec)添加一个额外的指令。

结论

在这个由两部分组成的系列中,您了解了 Linux 生态系统中使用的服务管理守护程序。 然后,您探索了 systemd 的基础知识并将这些基础知识应用于一个实际示例:配置数据库以在重新启动或崩溃后重新启动。 如果您想了解有关 systemd 的更多信息,请考虑探索 我们关于使用 systemctl 的综合教程。