唠唠闲话

在 Linux 系统中,服务管理是系统维护和操作的重要组成部分。systemctl 是用于管理 systemd 系统和服务管理器的命令行工具,与旧的服务管理命令(如 servicechkconfig)相比,systemctl 提供了一个更加强大和统一的方式来管理系统服务。

常见命令及其作用

我们主要通过以下命令来控制和查询服务的状态:

命令 作用
start 启动服务
stop 停止服务
restart 重启服务
reload 重新加载服务配置,不中断服务
enable 设置服务为开机自启动
disable 禁用服务开机自启动
status 显示服务的当前状态
is-active 检查服务当前是否正在运行
is-enabled 检查服务是否设置为开机自启动
daemon-reload 重新加载 systemd 的配置文件,通常在修改服务文件后使用

除了基本命令,systemctl 还提供了一些高级功能,例如 systemctl --failed 查看失败的服务,对于调试和诊断系统问题很有帮助。

服务管理

在 systemd 中,服务主要通过 .service 文件进行定义和管理,

文件位置及区别:

  • /etc/systemd/system/:通常存放自定义的服务文件,优先级最高。
  • /usr/lib/systemd/system//lib/systemd/system/:存放包管理器安装的服务文件,提供系统默认配置。
  • /run/systemd/system/:运行时生成的服务文件,用于临时覆盖。

文件定义好后,使用 sudo systemctl start [service_name] 启动服务,以及 sudo systemctl enable [service_name] 设置自启动。

服务文件编写

systemd 服务文件定义了如何管理和启动服务。要深入了解服务文件的更多细节,可以使用命令 man systemd.service 查看系统的手册页,或者访问 Ubuntu 官网的手册页面

我们举 frpc 的服务文件为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=frpc service
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
ExecStart=/home/user/software/frp/frpc -c /home/zhihong/software/frp/frpc.toml
ExecReload=/home/user/software/frp/frpc reload -c /home/zhihong/software/frp/frpc.toml
Restart=always
RestartSec=30s

[Install]
WantedBy=multi-user.target

主要区域:

  1. [Unit] 部分:提供了服务的描述和服务启动前的依赖关系。

    • Description:提供服务的简短描述。
    • After:指定服务依赖的其他单位。例如,network.target 表示服务需要在网络启动后启动,syslog.target 表示服务需要在系统日志启动后启动。
    • Wants:表示服务在启动时应尝试启动的其他单位,但这些单位的启动失败不会影响此服务的启动。
  2. [Service] 部分:描述了如何启动和管理服务。

    • Type:指定服务启动类型。常见的类型有 simpleforkingoneshot 等。
    • ExecStart:定义了启动服务时执行的命令。
    • ExecReload:定义了重载服务配置时执行的命令。
    • Restart:指定何时自动重启服务。
    • RestartSec:定义了在尝试重启服务前等待的时间。
  3. [Install] 部分:定义了如何安装这个单位,即如何将这个服务集成到系统的启动过程中。

    • WantedBy:指定安装目标,如 multi-user.target,表示服务应该在多用户模式下启动。

服务状态和日志

使用 systemctl status [service_name] 查看特定服务的当前状态。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ sudo systemctl status frpc
● frpc.service - frpc service
Loaded: loaded (/usr/lib/systemd/system/frpc.service; enabled; vendor pres>
Active: active (running) since Mon 2024-01-29 13:15:21 CST; 28min ago
Process: 196940 ExecReload=/home/zhihong/software/frp/frpc reload -c /home/>
Main PID: 193279 (frpc)
Tasks: 13 (limit: 309049)
Memory: 9.5M
CGroup: /system.slice/frpc.service
└─193279 /home/zhihong/software/frp/frpc -c /home/zhihong/software>

1月 29 13:15:21 f1 systemd[1]: Started frpc service.
1月 29 13:43:23 f1 systemd[1]: Reloading frpc service.
1月 29 13:43:23 f1 frpc[196940]: reload success
1月 29 13:43:23 f1 systemd[1]: Reloaded frpc service.

这个状态报告提供了关于 frpc 服务的运行状态、资源使用情况和最近的活动:

  1. 运行状态

    • ● frpc.service - frpc service:这显示了服务的名称和描述。
    • Loaded: loaded (/usr/lib/systemd/system/frpc.service; enabled; vendor pres>:表明 frpc.service 已被加载,位于 /usr/lib/systemd/system/ 目录中,并且被启用(enabled),这意味着它被配置为在启动时自动运行。
    • Active: active (running) since Mon 2024-01-29 13:15:21 CST; 28min ago:指示服务当前是活动的并正在运行
  2. 进程及资源

    • Process: 196940 ExecReload=/home/zhihong/software/frp/frpc reload -c /home/>:显示了最近执行的进程,这里是重载操作,包括具体执行的命令。
    • Main PID: 193279 (frpc):主进程的 ID 和名称。
    • Tasks: 13 (limit: 309049):服务正在使用 13 个任务。
    • Memory: 9.5M:服务使用 9.5 MB 的内存。
    • CGroup: /system.slice/frpc.service:显示了服务属于哪个控制组(CGroup)。
  3. 服务日志

    • 1月 29 13:15:21 f1 systemd[1]: Started frpc service.:指出服务在指定时间被启动。
    • 1月 29 13:43:23 f1 systemd[1]: Reloading frpc service.:服务在指定时间开始重新加载。
    • 1月 29 13:43:23 f1 frpc[196940]: reload success:显示了重载操作成功的信息。
    • 1月 29 13:43:23 f1 systemd[1]: Reloaded frpc service.:指出服务重载完成。

服务的日志对于故障排除和监控服务行为至关重要,通常先查看应用程序本身的日志,比如 frpc 的日志文件在 frpc.toml 中指定。更一般地,可以用 journalctl -u [service_name] 查看服务的系统日志。

案例实践

最后,我们再举一个简单的实践。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=测试脚本
After=network.target syslog.target

[Service]
Type=simple
# 默认参数为 nobody
User=rex
ExecStart=/home/rex/hello
# 服务异常退出时重启
Restart=on-failure
# 重启间隔
RestartSec=10s

[Install]
WantedBy=multi-user.target
1
2
3
4
#!/usr/bin/env bash
echo hello, $USER, $HOME # 默认为空
touch /home/rex/hello.log # 默认为 root 权限
echo hello >> /home/rex/hello.log

启动服务后,查看状态 sudo systemctl status test

1
2
3
4
5
6
7
● test.service - 测试脚本
Loaded: loaded (/lib/systemd/system/test.service; disabled; vendor preset: enabled)
Active: inactive (dead)

Jan 29 14:10:42 iZuf60qtfrn52d0p281tbmZ systemd[1]: Started 测试脚本.
Jan 29 14:10:42 iZuf60qtfrn52d0p281tbmZ hello[5559]: hello, ,
Jan 29 14:10:42 iZuf60qtfrn52d0p281tbmZ systemd[1]: test.service: Succeeded.

脚本执行一次后结束,状态显示为 inactive(dead)。如果将脚本改为 exit 3 异常退出,则因为 on-failure 规则,服务会不断尝试重新运行。

总结

本篇主要介绍了 systemctl 的基本命令和服务文件的结构,用于简化系统服务的管理。