首页/系统/Linux 运维命令速查/systemd 模板单元与多实例
systemd 与服务42 条

systemd 模板单元与多实例

模板单元(@.service)用一个文件拉起多实例:myapp@cluster1.service 等;%i 变量注入实例名,多租户/多端口场景利器。

Linux 运维命令速查系统更新于 2026-10-13

模板单元是什么

模板单元是文件名形如 worker@.service 的单元文件:@ 之前是模板名,启动时 @ 之后是实例名。worker@high.service 会用同一份模板生成一个独立实例,模板中的 %i 展开成 high。多队列、多端口、多租户这类同类服务只需维护一份配置。

基本信息

适用平台Linux + systemd(模板单元为 systemd 原生能力)
命令语法systemctl start|enable|stop 模板名@实例名.service
变量说明%i 实例名 / %I 反转义后的实例名 / %n 完整单元名 / %p 前缀
文件位置/etc/systemd/system/worker@.service;用户级在 ~/.config/systemd/user/

典型使用场景

  • 多队列消费:按队列名拉起 worker@queue1、worker@queue2,参数通过 %i 注入
  • 多端口监听:同一程序监听 8081/8082,实例名直接用端口号,一条命令批量拉起
  • 多租户隔离:每个租户一个实例,各自独立 cgroup 与重启策略,互不影响
  • 压测与灰度:临时拉起 worker@test 验证,用完 stop 即回收,不污染常驻实例
  • 统一升级:改一次模板文件,daemon-reload 后所有实例共享新配置

模板文件与实例操作

模板文件与实例操作
# /etc/systemd/system/worker@.service
[Unit]
Description=Worker %i
After=network-online.target
[Service]
ExecStart=/opt/worker/bin/run --queue %i
Restart=on-failure
[Install]
WantedBy=multi-user.target

常用命令

常用命令
systemctl daemon-reload                        # 新增或修改模板后必须执行
systemctl enable --now worker@high.service     # 启用并立即拉起一个实例
systemctl enable --now worker@high worker@low  # 一次拉起多个实例
systemctl status 'worker@*' --no-pager         # 查看全部实例(通配符要加引号)
systemctl list-units 'worker@*' --all          # 含未运行的实例

命名与引用写法

写法含义注意
worker@.service模板文件本身不能直接 start,必须带实例名
worker@high.service实例单元名%i 展开为 high
'worker@*'通配符引用一组实例必须加引号,否则 shell 先按文件名展开
%I反转义实例名把 - 还原为 /,实例名含斜杠时使用
实例名里的 - 是 systemd 的转义分隔符,-- 表示斜杠;命名多段标识时用点或下划线可以少踩转义的坑。
模板单元的 [Install] 对每个实例单独生效:enable worker@a 只影响 a 实例,新增实例要单独 enable 才会开机自启。
所有实例共用一份模板,ExecStart 中写死的参数对所有实例相同;差异化配置只能通过 %i 传参或 EnvironmentFile=%i.env 注入。

实例相关对象

对象写法说明
模板单元文件单元名中含实例占位符不含具体实例名
实例单元名模板名加实例名启动与查询都用这个
实例的覆盖片段路径中带实例名只影响该实例
批量操作通配符要加引号避免被 shell 先展开
启用状态核对按通配符列出单元文件核对数量与预期一致
多实例服务的常见做法是每个实例监听不同端口或使用独立数据目录,差异通过实例参数传入,模板保持一致;实例数量增长后要留意资源总量与日志分散程度,集中采集与统一模板能显著降低维护成本,也让扩容变成新增一个实例这么简单的事。

易错点

  • 不带实例名执行 start worker@ 或 worker@.service 会报 Unit not found,模板必须配实例名才能解析
  • 修改模板后忘记 daemon-reload,unit 状态仍是旧配置,甚至会报 Unit not found 掩盖真实原因
  • 通配符 worker@* 不加引号时 shell 会先做文件名展开,参数被替换成本目录下的文件名,systemctl 行为不可预期
  • 实例数量多时逐个 enable 容易漏,落盘前用 systemctl list-unit-files 'worker@*' 核对启用状态
  • 实例数变多后逐个手工操作:漏掉一个实例往往要等业务报障才发现,启停与核查都应按通配符批量执行并核对数量

数据来源与参考

  • man 5 systemd.unit(模板与 % 说明符)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌