前言

在使用 systemd 管理服务时,systemctl 是一个非常重要的命令行工具。服务配置文件通常位于 /etc/systemd/system/ 目录中,并以 .service 为扩展名。以下是一些常用的服务配置选项及其说明

[Unit] 部分

  • Description: 服务的简短描述,用于说明服务的功能。
  • Documentation: 指定服务的文档链接,通常是一个 URL。
  • After: 指定服务启动的顺序,表示该服务应在指定的服务之后启动。
  • Before: 指定服务启动的顺序,表示该服务应在指定的服务之前启动。
  • Requires: 指定该服务所依赖的其他服务,如果依赖的服务未能启动,该服务也不会启动。
  • Wants: 类似于 Requires,但如果依赖的服务未能启动,该服务仍然会启动。
  • Conflicts: 指定与该服务冲突的其他服务,如果冲突的服务正在运行,该服务将不会启动。

[Service] 部分

  • Type: 指定服务的类型。常见的类型包括:

    • simple: 默认类型,服务在启动后立即返回。
    • forking: 服务会在启动时创建一个子进程,父进程会退出。
    • oneshot: 服务执行一次并退出,通常用于初始化任务。
    • notify: 服务在启动时会发送通知,告知 systemd 服务已准备好。
    • idle: 服务在所有排队的任务执行完后启动。
  • ExecStart: 指定启动服务时执行的命令。可以是绝对路径或相对路径。

  • ExecStop: 指定停止服务时执行的命令。

  • ExecReload: 指定重新加载服务配置时执行的命令。

  • WorkingDirectory: 指定服务的工作目录。

  • User: 指定以哪个用户身份运行服务。

  • Group: 指定服务运行的用户组。

  • Environment: 设置环境变量,可以用多次指定不同的变量。

  • Restart: 指定服务失败后如何处理。常见选项有:

    • no: 不重启(默认)。
    • always: 无论服务如何退出都重启。
    • on-failure: 仅在非零退出状态时重启。
    • on-abort: 仅在服务因未捕获的信号而退出时重启。
  • RestartSec: 指定在重启服务之前等待的秒数。

  • TimeoutStartSec: 指定服务启动的超时时间。

  • TimeoutStopSec: 指定服务停止的超时时间。

  • LimitNOFILE: 设置服务可以打开的最大文件描述符数量。

[Install] 部分

  • WantedBy: 指定服务的目标(target),用于定义该服务在何时启动。常见的目标包括 multi-user.targetgraphical.target
  • RequiredBy: 指定服务的依赖目标,如果目标被启用,则该服务也会被启用。

示例服务文件

以下是一个简单的示例服务文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=My Example Service
After=network.target

[Service]
Type=simple
User=myuser
Group=mygroup
WorkingDirectory=/home/myuser/myapp
ExecStart=/usr/bin/myapp --option value
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

systemctl 命令

  • 启动服务: sudo systemctl start myservice.service
  • 停止服务: sudo systemctl stop myservice.service
  • 重启服务: sudo systemctl restart myservice.service
  • 查看服务状态: sudo systemctl status myservice.service
  • 启用服务: sudo systemctl enable myservice.service(在启动时自动启动)
  • 禁用服务: sudo systemctl disable myservice.service

日志管理

查看日志

显示最后num行的日志,如果省略num,则默认显示最后10行:

1
journalctl -n [num]

实时滚动显示最新日志:

1
journalctl -f

显示指定unit的日志,unit_name为具体的unit名称, 如果想合并显示多个unit日志可以用多个-u

1
journalctl -u <unit_name> -f

日志默认分页输出,–no-pager改为正常的标准输出:

1
journalctl --no-pager

显示从某个时间点之后的数据:

1
2
3
4
journalctl --since=“2023-08-31 10:00:00” #显示2023年8月31日10点以后的数据
journalctl --since “10 min ago” #显示最近10分钟内的日志
journalctl --since today/yesterday #显示今天/昨天以来的日志
journalctl --since “2023-08-31 10:00:00” --until “2023-08-31 11:00:00” #显示某个时间段内的日志(2023-08-31 10点-11点)

查看系统内核日志:

1
journalctl -k

获取指定进程的日志:

1
journalctl _PID=1234

手动清理日志

查看日志占用空间:

1
journalctl --disk-usage

日志归档(rotate是日志操作中的一个术语,其归档旧日志,后续日志写入新创建的日志文件中):

1
sudo journalctl --rotate

按时间清理日志:

1
2
3
4
5
6
# 清理1天之前的日志
sudo journalctl --vacuum-time=1d
# 清理1小时之前的日志
sudo journactl --vacuum-time=1h
# 清理1秒之前的日志
sudo journalctl --vacuum-time=1s

自动管理日志

1
2
3
sudo vim /etc/systemd/journald.conf
# 保存后记得重新加载
sudo systemctl restart systemd-journald

[Journal] 段的参数:

  1. Storage=auto
    指定日志存储类型。auto 表示根据系统的可用性自动选择存储方式(持久性存储或临时存储)。
  2. Compress=yes
    启用日志压缩,以减少存储空间的使用。
  3. Seal=yes
    启用日志密封功能,防止日志在写入后被修改,确保日志的完整性。
  4. SplitMode=uid
    指定日志文件的分割模式。uid 表示按照用户 ID 分割日志文件。
  5. SyncIntervalSec=5m
    设置日志同步的时间间隔。每 5 分钟同步一次日志到持久存储。
  6. RateLimitIntervalSec=30s
    设置速率限制的时间间隔。日志消息的速率限制在 30 秒内。
  7. RateLimitBurst=10000
    设置在 RateLimitIntervalSec 指定的时间间隔内允许的最大消息数量。这里是 10000 条消息。
  8. SystemMaxUse=
    设置系统日志使用的最大存储空间。未设置时,使用默认值。
  9. SystemKeepFree=
    保留的最小可用空间,确保系统有足够的空间。
  10. SystemMaxFileSize=
    设置单个日志文件的最大大小。未设置时,使用默认值。
  11. SystemMaxFiles=100
    设置系统日志文件的最大数量。超过这个数量的旧日志将被删除。
  12. RuntimeMaxUse=
    设置运行时日志使用的最大存储空间。未设置时,使用默认值。
  13. RuntimeKeepFree=
    保留的最小可用空间,确保运行时有足够的空间。
  14. RuntimeMaxFileSize=
    设置单个运行时日志文件的最大大小。未设置时,使用默认值。
  15. RuntimeMaxFiles=100
    设置运行时日志文件的最大数量。超过这个数量的旧日志将被删除。
  16. MaxRetentionSec=
    设置日志保留的最大时间。未设置时,使用默认值。
  17. MaxFileSec=1month
    设置单个日志文件的最大保留时间为 1 个月。
  18. ForwardToSyslog=yes
    启用将日志转发到 syslog 的功能。
  19. ForwardToKMsg=no
    禁用将日志转发到内核消息的功能。
  20. ForwardToConsole=no
    禁用将日志转发到控制台的功能。
  21. ForwardToWall=yes
    启用将日志消息转发到所有用户的墙(wall)消息。
  22. TTYPath=/dev/console
    指定用于输出的 TTY 设备路径,这里是控制台设备。
  23. MaxLevelStore=debug
    设置存储日志的最大级别为 debug,即所有级别的日志都将被存储。
  24. MaxLevelSyslog=debug
    设置转发到 syslog 的最大级别为 debug,即所有级别的日志都将被转发。
  25. MaxLevelKMsg=notice
    设置转发到内核消息的最大级别为 notice,只有 notice 及以上级别的日志将被转发。
  26. MaxLevelConsole=info
    设置转发到控制台的最大级别为 info,只有 info 及以上级别的日志将被输出到控制台。
  27. MaxLevelWall=emerg
    设置转发到墙消息的最大级别为 emerg,只有 emerg 级别的日志将被转发。
  28. LineMax=48K
    设置单行日志的最大字节数为 48K,超过这个大小的日志将被截断。
  29. ReadKMsg=yes
    启用从内核消息读取日志的功能。
  30. Audit=no
    禁用审计日志记录功能。

timer

systemd 定时器单元文件(.timer 文件)用于配置定时任务,允许您在特定时间或时间间隔触发其他服务单元(.service 文件)。以下是 timer 文件中的常用配置选项及其说明:

[Unit] 部分

  • Description: 定时器的简短描述。这个字段用于提供定时器的基本信息。

[Timer] 部分

  • OnActiveSec=: 从定时器激活开始的延迟时间。在这个时间段后,定时器将触发指定的服务。例如,OnActiveSec=5min 表示在激活后的 5 分钟后触发。

  • OnBootSec=: 在系统启动后的延迟时间内触发定时器。例如,OnBootSec=10min 表示在系统启动后 10 分钟触发。

  • OnCalendar=: 使用日历时间格式设置定时器的触发时间。可以使用类似 *-*-* 01:30:00 的格式来指定每天的 01:30 触发,也可以使用其他复杂的日历表达式。

  • OnStartupSec=: 相对于 systemd 被首次启动的时间点,也就是内核启动init进程的时间点。

  • OnUnitActiveSec=: 相对于匹配单元最后一次被启动的时间点。

  • OnUnitInactiveSec=: 相对于匹配单元最后一次被停止的时间点。

  • Unit=: 指定该定时器触发的服务单元(.service 文件)。例如,Unit=my_service.service

  • Persistent=: 如果设置为 true,当定时器在指定的时间未能触发(例如,系统在该时间关闭),那么在下次系统启动时会立即触发该定时器。默认值为 false

[Install] 部分

  • WantedBy=: 指定定时器的目标,通常为 timers.target,表示该定时器应该在目标中启用。

示例

以下是一个完整的定时器配置示例,结合了上述选项:

1
2
3
4
5
6
7
8
9
[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=*-*-* 02:00:00 # 每天凌晨 2 点
Unit=backup.service # 触发的服务

[Install]
WantedBy=timers.target # 启用时将其添加到 timers.target

日历表达式

OnCalendar 支持多种格式,以下是一些示例:

  • Mon..Fri 09:00:00:每周一到周五的 09:00。
  • * * * 12:00:00:每天中午 12 点。
  • *-*-* 01:30:00:每天的 01:30。
  • * * * *:00:每小时的整点触发。

其他注意事项

  • 时间格式:可以使用 ISO 8601 格式的时间表示法。
  • 调试:使用 systemctl list-timers 查看所有定时器及其状态。
  • 日志:通过 journalctl -u <service-name> 查看服务日志,以确保定时器按预期工作。