⏰ 第02章 · 服务管理

start/stop/enable/status/restart

服务管理

上一章认识了 systemd 是什么;这一章动手操作一个服务:怎么把它启动/停止/重启,怎么让它开机自启,以及怎么看它现在到底活得怎么样。你平时说的"重启一下 bangdream""让 dsh 别自己开机"就是这几个动作的组合。

服务的状态机

一个 systemd 服务有明确的活动(active)状态和开机(enabled)状态,它们是完全独立的两个维度。务必分开理解。

现在是否在跑 —— active/inactive/dead:

systemctl status bangdream.service   # 看 Active: active (running) 还是 inactive (dead)
systemctl is-active bangdream        # 输出 active / inactive / failed 之一

开机是否自启 —— enabled/disabled:

systemctl is-enabled bangdream       # 输出 enabled / disabled / masked / static
systemctl status bangdream           # 第一行也写着 enabled 还是 disabled
状态 含义 怎么造成
active (running) 正在运行 start,或开机自启后
inactive (dead) 已停止 stop 之后
failed 启动失败/中途崩溃 进程退出码非 0
enabled 开机会启动 enable
disabled 开机不启动 disable
masked 被屏蔽,无法启动 mask,安全手段

提示 Active: active (running),括号里说明子状态。最常看到 running(在跑)、dead(没跑)、failed(挂了)、exited(一次性任务已结束)。

核心四个动作:start / stop / restart / reload

# 启动
systemctl start bangdream.service
# 停止
systemctl stop bangdream.service
# 重启(先停再起,服务全程不可用)
systemctl restart bangdream.service
# reload:优雅重载配置(仅部分支持 SIGHUP 的服务)
systemctl reload nginx.service

start/stop/restart 是改变"现在状态"的;它们不影响开机是否自启。也就是说 systemctl stop 之后你若重启机器,服务照样会起来(如果它是 enabled)。

易错 分不清 restart 与 reload。restart 是彻底杀掉进程再重跑,连接会断、会有一小段不可用窗口;reload 是让进程在不退出的情况下重读配置文件,更平滑。但 reload 只在服务实现 SIGHUP 处理时有效,否则报错,并退化为直接忽略。

开机自启:enable / disable

# 开机自启
systemctl enable bangdream.service
# 取消开机自启
systemctl disable bangdream.service
# enable 通常附带 start;若只想配自启但不立刻启动,加 --now
systemctl enable --now bangdream.service        # enable + 立即 start

enable 的神奇之处只在第 1 章提过的 [Install] WantedBy=multi-user.target 上:它会在 /etc/systemd/system/multi-user.target.wants/ 里为这个服务创建一个符号链接,于是开机进入多用户模式时,它被自动拉起。

ls -l /etc/systemd/system/multi-user.target.wants/ | grep bangdream
# lrwxrwxrwx ... bangdream.service -> /etc/systemd/system/bangdream.service

注意 只有 unit 文件里写了 [Install] 段,enable 才有效。如果 is-enabled 返回 static,表示它本身不做 enable 而是会被别的单元引用;masked 则表示被屏蔽(见下文)。

屏蔽而不是禁用:mask / unmask

disable 只是不开机自启,你仍能手动 start。若想"彻底不许任何人启动它",用 mask——它会用一个链接把它盖住,start 都报错。

systemctl mask xxx.service    # 永久屏蔽
systemctl unmask xxx.service  # 解除

易错 这台机器上 cryptdisks-early.service / cryptdisks.service 就是 masked 状态——在无加密磁盘的云主机上是正常现象,别被第一眼吓到。

详细解读 status 输出

systemctl status bangdream.service 是信息量最大的一条命令,拆开看:

● bangdream.service - BanG Dream! Character Database API Server
     Loaded: loaded (/etc/systemd/system/bangdream.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-09-07 20:41:28 UTC; 16h ago
   Main PID: 16643 (MainThread)
      Tasks: 11 (limit: 19145)
     Memory: 38.7M (peak: 39.9M)
        CPU: 1.495s
     CGroup: /system.slice/bangdream.service
             └─16643 /usr/local/bin/node server.js
  • Active: 一行的 since ... 16h ago 告诉你它已在跑 16 小时;
  • Main PID: 是主进程编号,后面跟的命令是真实的启动命令;
  • Memory: 38.7M 是当前内存,peak 是峰值;
  • Tasks 是该服务(含子进程)的线程/任务数;
  • 末尾的空行是最近日志,由 journald 提供。
systemctl status bangdream.service   # 看全部
systemctl status --no-pager bangdream  # 不想翻页时加 --no-pager

提示 手工加 --no-pager 能避免日志太长时进入 less 分页,写脚本或贴文档时尤其好用;systemctl 也支持环境变量 SYSTEMD_PAGER=cat 全局禁用。

一个真实场景:重启 dsh,让新配置生效

假设你刚改了 DeepSeek Harness 的 Web 服务配置,要让它生效:

systemctl restart dsh.service
systemctl status dsh.service --no-pager          # 确认 State 变成 running
journalctl -u dsh.service -n 20 --no-pager       # 看有没有报错(第 5 章细讲)

改完一定用 status 或 is-active 复核一遍,确认 active (running),别光看命令没报错就以为成功了。

易错点

  • enable 不立即启动:enable 只配开机自启,现在不启动。要"现在就起 + 以后开机都起",用 enable --now。
  • 改了 unit 文件不 reload 白改:第 3 章细讲,但这里先记住——改完 /etc/systemd/system/*.service 一定要 systemctl daemon-reload 再 restart。
  • failed 不是 dead:服务崩了会变 failed,start 之前最好 reset-failed 清一下失败标记,否则 systemctl 可能拒绝再次启动。
  • 用错单位名大小写:unit 文件按文件名大小写敏感,Bangdream.service 和 bangdream.service 是两个东西。
  • 服务没起来先看日志:status 的底部日志、journalctl -u xxx 往往直接写明原因(端口占用、缺依赖、磁盘满),比瞎猜快得多。

相关命令

start、stop、restart、reload、enable、disable、mask、status、is-active、is-enabled、reset-failed、daemon-reload。