环境:
- debian13.7
参考:
一、systemd 介绍
systemd 是现代 Linux 系统中一套核心的系统和服务管理器,它作为 PID 1 运行,负责在内核启动后初始化用户空间,并持续管理系统的服务、设备、挂载点、网络、日志等。
1.1 systemd 不只是一个 init 程序,而是一个庞大的工具集,包含:
- init 守护进程:PID 1,启动并管理所有用户空间进程。
- 服务管理器:用声明式单元文件管理服务生命周期。
- 日志系统:systemd-journald 收集内核和用户空间日志。
- 登录管理:systemd-logind 管理用户会话、电源操作。
- 网络管理:systemd-networkd、systemd-resolved。
- 时间同步:systemd-timesyncd。
- 定时任务:systemd.timer 替代 cron。
- 设备管理:systemd-udevd 处理内核设备事件。
1.2 优点与争议
优点:
- 启动快、依赖管理强、配置统一。
- 日志集中、查询方便。
- 资源控制、沙箱、安全特性丰富。
- 活跃开发,主流发行版默认采用。
争议:
- 违反 Unix"小而专"哲学,功能过于庞大。
- 二进制日志不便于直接用文本工具处理。
- 复杂性高,学习曲线陡。
- 与部分发行版和社区理念冲突(如 Devuan、Artix 等衍生版专门去除 systemd)。
1.3 现状
主流发行版: Ubuntu、Debian、Fedora、RHEL、CentOS、Arch、openSUSE、Deepin、openEuler 等均默认使用 systemd。
非 systemd 发行版: Alpine(OpenRC)、Gentoo(可选 OpenRC)、Void(runit)、Devuan(sysvinit)、Artix(多种)等。
容器与嵌入式: systemd 也用于部分容器和嵌入式系统,但轻量级替代品(如 OpenRC、runit、s6)仍有优势。
二、配置一个简单的后台服务
抛开复杂的功能不谈,我们最常用的就是使用 systemd 配置一个后台服务,下面我们基于 .net10 的单文件配置一个 web 服务
2.1 准备 .net10 单文件 web服务器代码
文件: /root/Program.cs
csharp
#:sdk Microsoft.NET.Sdk.Web
var builder = WebApplication.CreateBuilder();
var app = builder.Build();
// 启动时打印到日志(会进入 journald)
var aspnetEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var MY_VAR= Environment.GetEnvironmentVariable("MY_VAR");
Console.WriteLine($"启动环境: ASPNETCORE_ENVIRONMENT={aspnetEnv}, MY_VAR={MY_VAR}");
app.MapGet("/echo", () => $"echo {DateTime.Now}\n");
app.Run();
2.2 写 *.service 文件
新建文件 /etc/systemd/system/webecho.service
text
[Unit]
Description=ASP.NET Core Echo Web Service (single-file)
After=network.target
[Service]
Type=simple
WorkingDirectory=/root
ExecStart=/usr/bin/dotnet run /root/Program.cs
Environment=ASPNETCORE_ENVIRONMENT=Test123
Environment="MY_VAR=hello world"
Restart=on-failure
RestartSec=5
User=root
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
2.3 重载 systemd ,开启web服务
配置好后,重新加载 systemd 并启动服务:
shell
systemctl daemon-reload # 重载systemd
systemctl start webecho # 运行服务
systemctl enable webecho # 开机自启动
查看日志:
shell
journalctl -u webecho -f
整体效果如下:

然后,我们换个终端:
查看服务状态:systemctl status webecho.service

然后,访问下这个web服务:curl httpL//localhost:5000/echo

这样,一个简单的守护进程服务就配置好了,即使中间程序挂掉 linux 也会自动拉起,并且机器重启也会自动启动。
三、systemctl 管理命令
3.1 常见命令
shell
# 针对一个服务
systemctl start webecho # 启动
systemctl stop webecho # 停止
systemctl restart webecho # 重启
systemctl status webecho # 查看服务状态
systemctl enable webecho # 创建符号链接,让服务开机自启
systemctl disable webecho # 删除符号链接,取消开机自启
systemctl mask webecho # 把服务链接到 /dev/null,彻底禁止启动
systemctl unmask webecho # 删除指向 /dev/null 的链接,恢复服务
systemctl cat webecho # 查看最终生效的单元文件
systemctl edit webecho # 创建 override 片段并编辑
systemctl edit --full webecho # 编辑完整单元文件
systemctl show webecho # 显示所有属性
systemctl list-dependencies webecho # 查看依赖关系
systemctl reset-failed webecho # 清除失败状态
# 不针对具体服务
systemctl list-units --type=service # 列出所有活动服务
systemctl list-unit-files --type=service # 列出所有服务文件及启用状态
systemctl daemon-reload # 修改单元文件后必须重载
3.2 解释 enable/disable/mask/unmask
只针对 systemd unit(.service 服务文件) ,控制开机自启 和能否启动 ,不影响当前正在运行的服务(启停是 start/stop)
3.2.1. systemctl enable xxx.service
作用:设置开机自动启动
- 本质:创建软链接,把 unit 加入开机目标(multi-user.target.wants 等)
- ✅ 开机时自动拉起服务
- ✅ 你依然可以手动
systemctl start xxx启动 /stop 停止 - ❗ enable ≠ 现在就运行服务,只是配置开机策略
shell
systemctl enable myapp.service
3.2.2 systemctl disable xxx.service
作用:取消开机自动启动
- 本质:删除 enable 创建的软链接
- ❌ 开机不再自动启动
- ✅ 仍然可以手动 start 启动服务
shell
systemctl disable myapp.service
3.2.3 systemctl mask xxx.service
作用:彻底锁定、禁止启动服务(最强限制)
- 本质:将服务链接到
/dev/null - ❌ 开机不会启动
- ❌ 就算手动 systemctl start 也启动失败
用来防止意外启动,比如冲突服务、废弃服务
shell
systemctl mask myapp.service
3.2.4 systemctl unmask xxx.service
作用:解除 mask 锁定
- 删掉指向
/dev/null的链接,恢复服务文件原始状态 - unmask 之后,才能 start /enable
shell
systemctl unmask myapp.service
3.2.5一句话对比表
| 命令 | 开机自启 | 能否手动 start | 核心目的 |
|---|---|---|---|
| enable | ✅ 是 | ✅ 可以 | 设置开机自启 |
| disable | ❌ 否 | ✅ 可以 | 关闭开机自启 |
| mask | ❌ 否 | ❌ 不可以 | 禁止任何方式启动 |
| unmask | 保持原有状态 | ✅(解锁后) | 解除 mask 锁定 |
3.2.6 重要组合逻辑
mask优先级 >enable。mask 之后,enable 失效,哪怕你 enable 了也无法启动- mask 不会自动 disable;mask + enable 这种组合:开机不启动,手动也不能启动
- 查看状态:
shell
# 查看是否开机自启 + 是否被mask
systemctl is-enabled myapp.service
返回值:
enabled:已 enable 开机自启disabled:已关闭开机自启masked:被 mask 锁定
3.3 如何新建一个后台服务
常用组合为:
shell
systemctl daemon-reload # 重载systemd
systemctl start webecho # 运行服务
systemctl enable webecho # 开机自启动
3.4 如何删除一个后台服务
直接删除 .service 文件通常不够,因为 systemd 可能还在内存里保留着这个单元,而且如果服务正在运行,删文件并不会停止进程。正确做法是:先停止、禁用、解除屏蔽,再删文件,最后重载 systemd。
正确的删除步骤:
shell
# 1. 停止正在运行的服务
systemctl stop webecho
# 2. 取消开机自启(删除 enable 生成的符号链接)
systemctl disable webecho
# 3. 如果之前 mask 过,先解除屏蔽
systemctl unmask webecho
# 4. 删除服务文件
rm -f /etc/systemd/system/webecho.service
# 5. 如果有 override 片段目录,也一并删除
rm -rf /etc/systemd/system/webecho.service.d
# 6. 重新加载 systemd 配置
systemctl daemon-reload
# 7. 清除失败状态(可选)
systemctl reset-failed webecho
四、查看服务日志
systemd 日志:journalctl(你部署 .net echo 服务直接用)
journald 是 systemd 的日志守护进程,日志二进制存储,用
journalctl查询;systemctl status xxx 只会展示最近几行日志,详细日志靠 journalctl
4.1 最常用
shell
# 查看 webecho 服务全部日志
journalctl -u webecho.service
# 实时跟踪日志(类似 tail -f,调试接口最常用)
journalctl -u webecho.service -f
# 只看本次开机后的 webecho 日志
journalctl -u webecho.service -b
# 看上次开机的日志(服务上次崩溃重启排查)
journalctl -u webecho.service -b -1
# 看最近20条日志
journalctl -u webecho.service -n 20
4.2 时间过滤 --since /--until
shell
# 最近30分钟日志
journalctl -u webecho.service --since "30 min ago"
# 今天0点至今
journalctl -u webecho.service --since today
# 指定时间段
journalctl -u webecho.service --since "2026-10-02 07:00:00" --until "2026-10-02 09:00:00"
4.3 日志级别过滤 -p
级别:0 emerg、1 alert、2 crit、3 err、4 warn、5 notice、6 info、7 debug
shell
# 只看错误及更严重(err、crit、alert、emerg)
journalctl -u webecho.service -p err
# 警告到错误区间
journalctl -u webecho.service -p warn..err
4.4 输出格式 -o
shell
# json格式,方便程序解析
journalctl -u webecho.service -o json-pretty
# 精确时间戳
journalctl -u webecho.service -o short-iso
4.4 日志磁盘管理(journal 占用清理)
shell
# 查看journal日志占用大小
journalctl --disk-usage
# 保留最近500M日志,旧的删除
journalctl --vacuum-size=500M
# 只保留最近7天日志
journalctl --vacuum-time=7d
五、其他问题
5.1 自己新建个服务,它必须以 *.service 后缀吗?
是的,而且必须调用 systemctl daemon-reload systemd 才会加载的内存
5.2 什么是 target?*.sevice 中的 WantedBy=multi-user.target 是什么意思?
在 systemd 中,target 是一组 unit 的集合,用来把系统启动或运行过程中的相关服务、挂载、套接字等组织在一起,形成一个同步点或阶段。它本身通常不执行实际工作,而是通过依赖关系把其他 unit "拉"起来。
target 与 service 的关系:
- service 是"干活"的单元。
- target 是"组织"的单元,把一组 service 聚合起来。
- service 通过 WantedBy= 声明自己属于哪个 target。
- target 可以嵌套依赖其他 target,形成启动链。
那么,service 如何和 target 关联起来呢?通过 service 文件的 WantedBy=multi-user.target 关联,可以通过下面查看依赖以及启动关系:systemd-analyze critical-chain

5.3 怎么控制服务依赖启动呢?

5.4 linux一般自带了哪些 service 呢?
