构建时 systemd 调度

Lobsters Hottest 工具

摘要

文章探讨了使用 NixOS 来检查和管理自托管服务的构建时 systemd 调度,以增强运行时检查。

<p><a href="https://lobste.rs/s/irgjfw/build_time_systemd_schedule">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/17 08:07

# 构建时 systemd 调度 来源:https://gvolpe.com/blog/systemd-schedule/ 缩略图 系统和服务管理器 [systemd](https://systemd.io/) 为 Linux 系统提供了基础构建模块,也是 NixOS 的默认选择——尽管目前也有一些替代方案,如 [finix](https://github.com/finix-community/finix) 和 [sixos](https://codeberg.org/amjoseph/sixos),正在探索这一设计领域。作为一名在 NixOS 服务器上托管若干服务的自建用户,它已成为我工具箱中的常备项。 *当前服务器拓扑图,由 nix-topology(https://oddlama.github.io/nix-topology/)生成(附带少量自定义补丁)❄️* ## 运行时调度 最近,我在其中一台运行 [Immich](https://gvolpe.com/blog/immich-photos) 的服务器上进行了一些升级和维护,并想检查当前的作业调度情况,以确认它们在我的时区中配置正确。 ``` [admin@metropolis:~]$ systemctl list-timers --all NEXT LEFT LAST PASSED UNIT ACTIVATES Sat 2026-08-15 10:44:47 CEST 15min Sat 2026-08-15 10:14:47 CEST 14min ago disk-monitor.timer disk-monitor.service Sat 2026-08-15 11:00:00 CEST 30min Sat 2026-08-15 10:00:08 CEST 29min ago logrotate.timer logrotate.service Sat 2026-08-15 15:21:37 CEST 4h 52min Fri 2026-08-14 15:21:40 CEST 19h ago acme-renew-immich.gvolpe.com.timer acme-order-renew-immich.gvolpe.com.service Sat 2026-08-15 22:52:43 CEST 12h Fri 2026-08-14 22:52:43 CEST 11h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Sun 2026-08-16 00:00:00 CEST 13h Sat 2026-08-15 00:00:08 CEST 10h ago custom-immich-stop-trigger.timer custom-immich-stop-trigger.service Sun 2026-08-16 00:00:01 CEST 13h Sat 2026-08-15 00:00:08 CEST 10h ago postgresql-backup.timer postgresql-backup.service Sun 2026-08-16 00:00:05 CEST 13h Sat 2026-08-15 00:00:08 CEST 10h ago borgbackup-job-immich-s3-media.timer borgbackup-job-immich-s3-media.service Sun 2026-08-16 00:00:05 CEST 13h Sat 2026-08-15 00:00:08 CEST 10h ago borgbackup-job-postgres.timer borgbackup-job-postgres.service Sun 2026-08-16 00:00:30 CEST 13h Sat 2026-08-15 00:00:35 CEST 10h ago s3-replica.timer s3-replica.service Sun 2026-08-16 03:00:00 CEST 16h Sat 2026-08-15 03:00:08 CEST 7h ago s3ql-fsck.timer s3ql-fsck.service Sun 2026-08-16 03:30:00 CEST 17h Sat 2026-08-15 03:30:06 CEST 6h ago custom-immich-start-trigger.timer custom-immich-start-trigger.service Mon 2026-08-17 00:00:00 CEST 1 day 13h Mon 2026-08-10 02:00:08 CEST 5 days ago nix-gc.timer nix-gc.service Mon 2026-08-17 01:39:34 CEST 1 day 15h Mon 2026-08-10 02:52:22 CEST 5 days ago fstrim.timer fstrim.service 13 timers listed. ``` *随着作业数量的增加,很容易失去跟踪。* 然而,查看这些信息让我产生了一个疑问:是否可以在我部署之前,直接从 NixOS 配置中获取这些信息——即进行构建时检查,而非运行时检查。NixOS 的一个优秀特性是它在构建时会生成一个派生(derivation),这是整个系统的构建配方,易于检查;其中包含的 systemd 配置也不例外。 ``` nix-repl> nixosConfigurations.metropolis.config.systemd.timers { "acme-renew-immich.gvolpe.com" = { ... }; borgbackup-job-immich-s3-media = { ... }; borgbackup-job-postgres = { ... }; custom-immich-start-trigger = { ... }; custom-immich-stop-trigger = { ... }; disk-monitor = { ... }; fstrim = { ... }; logrotate = { ... }; nix-gc = { ... }; postgresql-backup = { ... }; s3-replica = { ... }; s3ql-fsck = { ... }; } nix-repl> nixosConfigurations.metropolis.config.systemd.timers.s3-replica.timerConfig { OnCalendar = "*-*-* 0:00:30"; Persistent = false; } ``` 因此信息是可用的,我们可以按需处理。在我的案例中,我想要为每个服务器的调度创建一个 Mermaid 流程图,结果如下(可在 [Mermaid Live](https://mermaid.live/edit#pako:eNqtlVtu2zgUhrdCMCh6geXoakua1EDdGH1rHprBAAO_0BQtc0yKGpJK4gRZy8wOurUuoRSlKLLj2GkR2TBE-vzU9x8eHd5BLDICU_jmDfhCCiKRJhlYSsEBuUKsssOv9ObiG1AbpQnPgKacSDWcF0smrvEKSQ0uz-cFMH9oRt7N4WUdABRekaxiBCyFPFvI0wk4W0w40VKUglF1drqYNNPvZpWZI6d_IanQ9fs5fF8vhhlS6pwsm1XBkjKWniSzaTIbDZRZZE3Sk6W9BlgwIdMTz1472pqk0U7jmTudvly7EEK30s9JLX65tCSSioziVj4bTUefvJfJW7v2t568dE1CTeI-OOYDXDe13y55uFJacIdyTvHKMfeloyXNcyKH1rsNOitN8OTHf_9_t7rTcgIO6BSRVxST_jYYiiaV3S4Dx5mYWUvobRFaQK8DLIXSuSTqX-YsEF5X5WGup-F7cbxHHINmWWwKL_2nLFHHshAyb1Z1_hGLznzgcJJRdBjsiLalbNVA6Q0jH982W5xLtPnj7cQUhaLmDSpMVSGmSL3stiu_58prXPl2EPyCq4cM_pKdTvQqPoKeD7_xEdhB-MRH8FjKJpeSlIziIzvRi3sV2rBHGzS0oR1EW7TBzpunAlOjS4XXx2gfwl4FNurBhg1sZAejHdjgYJswPfv3-kRfuPfNHPUAowZwZAfjBvCimJq--o3gjxEfgIviz4LqT1jTK1LPBS7vmDOq1g4X5n9xBHIrci_V2Hbzne41tlxxw5UhyjbdsxHmxFRZQa5b68P8SrCSDLHgh1msUsiMyGf1LygEiYpMcHprzt6MMLQBfrhq2uljhWyIelofcXf27JiNrdmkMbsSley5ZSKXQpuT_rC1x7C9OU6ee3TSNLT2ILsmZN179tKcivRITtuYrbytzE9Bb5wcH9a2Mb-Tc3c341pWe15Jz33OuGfORziAuaQZTGvxABpSjuohvKuD51CvCDeJTM1thuR6DufFvdGUqPhbCP4gk6LKVzC1TWEAqzIzu3BOkSHn3awpN1N1n0VVaJiOI7sGTO_gDUz9MBkmrhuEXhj5sZcEowHcwNSJ46HnReMwdt1k7Id-cD-At_ax3tB3_XHsB1EYJ7Efef79T2O6XiQ) 查看)\)。 调度图 这是通过一个 Python 脚本临时拼凑起来的,该脚本使用以下命令获取核心信息: ``` nix eval --json .#nixosConfigurations.metropolis.config.systemd.timers \ --apply 'builtins.mapAttrs (name: timer: timer.timerConfig)' | jq ``` 生成的 JSON 数据如下: ``` { "acme-renew-immich.gvolpe.com": { "AccuracySec": "86400s", "FixedRandomDelay": true, "OnCalendar": "daily", "Persistent": "yes", "RandomizedDelaySec": "24h", "Unit": "acme-order-renew-immich.gvolpe.com.service" }, "borgbackup-job-immich-s3-media": { "OnCalendar": "*-*-* 0:00:05", "Persistent": false }, "borgbackup-job-postgres": { "OnCalendar": "*-*-* 0:00:05", "Persistent": false }, "custom-immich-start-trigger": { "OnCalendar": "*-*-* 03:30:00", "Unit": "custom-immich-start-trigger.service" }, "custom-immich-stop-trigger": { "OnCalendar": "*-*-* 00:00:00", "Unit": "custom-immich-stop-trigger.service" }, "disk-monitor": { "OnBootSec": "5m", "OnUnitActiveSec": "30m" }, "fstrim": { "OnCalendar": [ "", "weekly" ] }, "logrotate": { "OnCalendar": [ "hourly" ] }, "nix-gc": { "OnCalendar": [ "weekly" ], "Persistent": true, "RandomizedDelaySec": "0" }, "postgresql-backup": { "OnCalendar": "*-*-* 0:00:01", "Unit": "postgresql-backup.service" }, "s3-replica": { "OnCalendar": "*-*-* 0:00:30", "Persistent": false }, "s3ql-fsck": { "OnCalendar": "*-*-* 03:00:00", "Persistent": false, "Unit": "s3ql-fsck.service" } } ``` 接下来,就是处理这些数据,以所需格式生成 Mermaid 图。 ### 时区 脚本按以下顺序评估,默认使用 UTC(如果两个值都缺失)。 ``` nix-repl> nixosConfigurations.metropolis.config.systemd.globalEnvironment.TZ "Europe/Warsaw" nix-repl> nixosConfigurations.metropolis.config.time.timeZone "Europe/Warsaw" ``` 虽然可以在每个服务单元单独设置多个时区,但这目前不是我需要的功能。 ## 运行时依赖 在运行的服务器上,我们可以使用以下命令生成 systemd 依赖关系图: ``` systemd-analyze dot --require --from-pattern="*.service" --to-pattern="*.service" \ | dot -Tsvg > services.svg ``` 这将为该 NixOS 服务器渲染出类似这样的图表: 依赖图 图表很快就会变得难以阅读,因此通常分析特定单元而非全部单元更为有用,例如: ``` [admin@metropolis:~]$ systemctl show immich-server.service -p Requires -p Wants Requires=postgresql.target s3ql-mount.service -.mount system-immich.slice Wants=-.mount ``` 这些工具对于日常的服务器维护任务很有用,但我们能否在不实际部署的情况下验证依赖关系? ## 构建时依赖 毫不意外,这些信息同样可在我们的 NixOS 配置蓝图中找到。 ``` nix-repl> nixosConfigurations.metropolis.config.systemd.services.s3 nixosConfigurations.metropolis.config.systemd.services.s3-aliases nixosConfigurations.metropolis.config.systemd.services.s3-replica nixosConfigurations.metropolis.config.systemd.services.s3ql-auth nixosConfigurations.metropolis.config.systemd.services.s3ql-fs nixosConfigurations.metropolis.config.systemd.services.s3ql-fsck nixosConfigurations.metropolis.config.systemd.services.s3ql-mount ``` 以下单行命令展示了如何直接从 NixOS 配置获取所有 systemd 依赖关系: ``` nix eval --json .#nixosConfigurations.metropolis.config.systemd.services \ --apply 'builtins.mapAttrs (name: service: { inherit (service) requires wants wantedBy requiredBy; })' \ | jq 'with_entries(.value |= with_entries(select(.value != []))) | with_entries(select(.value != {}))' ``` 为简洁起见,这里展示其生成的部分 JSON 数据: ``` { "immich-machine-learning": { "requires": [ "postgresql.target", "s3ql-mount.service" ], "wantedBy": [ "multi-user.target" ] }, "immich-server": { "requires": [ "postgresql.target", "s3ql-mount.service" ], "wantedBy": [ "multi-user.target" ] }, "nginx": { "wantedBy": [ "multi-user.target" ], "wants": [ "acme-immich.gvolpe.com.service" ] } } ``` 我还没有为此创建任何图表,但如果需要,我们已有必要的数据。 ## 最终想法 我认为这值得分享,因为 NixOS 总是让我感到惊喜 🤩。可以说我总是在学习新事物,更重要的是,在运行这些服务器时获得了极大的乐趣!强烈推荐。 你怎么看?请在下方评论区告诉我 👇 祝好, Gabriel。

相似文章

使用Nix构建系统软件

Lobsters Hottest

一篇博客文章,讨论Nix如何帮助解决构建系统软件时的依赖和可重现性问题,特别是针对像BPF和io_uring这样快速演进的子系统。

你对 systemd 定时器的爱还不够

Lobsters Hottest

本文提倡在 Linux 上使用 systemd 定时器替代传统的 cron 作业来执行定时任务,强调其更好的集成性、日志记录以及更清晰的语法。

后现代构建系统

Lobsters Hottest

一篇博客文章,探讨理想中的'后现代'构建系统的设计,该系统优先考虑可信的增量构建、最大化计算复用和分布式构建,并以Nix作为参考。

改进我的自托管 Actions Runner 设置

Lobsters Hottest

作者通过用 systemd-nspawn 容器替换 Docker 来改进其自托管的 Gitea Actions Runner 设置,以提高安全性,并详细说明了配置和权衡。