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

作为Write for DOnations计划的一部分,作者选择了免费和开源基金来接受捐赠

介绍

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

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

注意:您也可以考虑阅读我们非常流行的使用systemctl来控制 systemd 服务和单元的教程

先决条件

要完成本教程,您需要:

配置 MySQL 在启动后自动启动使用 systemd

安装 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*

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

Output
ls: 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/

Output
Created 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*

您将收到如下输出:

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

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

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

  • ps -ef | grep mysql

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

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

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

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

作为一个现代应用程序,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 服务手册页显示了下表中的重启参数:

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

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

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

ps -ef | 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

它会显示服务失败:

Output
mysqld.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 服务以在崩溃后自动启动。您所要做的就是在服务单元文件部分Restart(和可选的RestartSec添加一个额外的指令[Service]

结论

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

觉得文章有用?

点个广告表达一下你的爱意吧 !😁