模板单元是什么
模板单元是文件名形如 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 先展开 |
| 启用状态核对 | 按通配符列出单元文件 | 核对数量与预期一致 |
多实例服务的常见做法是每个实例监听不同端口或使用独立数据目录,差异通过实例参数传入,模板保持一致;实例数量增长后要留意资源总量与日志分散程度,集中采集与统一模板能显著降低维护成本,也让扩容变成新增一个实例这么简单的事。