如何将Linux服务配置为在崩溃或重启后自动启动-第2部分:参考
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
在本教程中,您将使用 systemd
将 MySQL 配置为在重启或崩溃后自动重启。
这是两部分系列的后半部分。 第一部分 涵盖了一般的 Linux 服务管理概念,例如 init
守护进程和运行级别。 它以 systemd
中的服务管理演示结束。 在这里,您将检查 targets
、wants
、requires
和 unit
文件。 这一部分,第二部分,提供了一个使用MySQL数据库的实际例子。
注意:你也可以考虑阅读我们非常流行的使用systemctl控制systemd服务和单元的教程。
先决条件
要完成本教程,您需要:
- 运行 CentOS 8 的服务器,包括具有 sudo 权限的非 root 用户。 要设置所有这些,包括防火墙,您可以 创建一个运行 CentOS 8 的 DigitalOcean Droplet,然后按照我们的 初始服务器设置指南 。
- 安装了 MySQL。 有关详细说明,请按照我们的教程 如何在 CentOS 8 上安装 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 服务单元文件中,两个参数 - Restart
和 RestartSec
- 控制崩溃行为。 第一个参数指定服务应该何时重新启动,第二个参数定义它应该在重新启动之前等待多长时间。
要测试崩溃行为,请使用 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 的综合教程。