systemctl is-active 返回 active 不代表服务真正可用,需结合进程存在性(如 pgrep)、端口监听及健康接口响应(如 curl)综合判断。

如何用 systemctl 判断服务是否真正运行中
很多用户误以为 systemctl is-active 返回 active 就代表服务可用,其实不然。这个状态只说明 systemd 认为该 unit 处于激活态,不校验进程是否存活、端口是否监听、健康接口是否响应。
实操建议:
-
systemctl is-active --quiet nginx适合脚本判断,但必须配合后续检查 - 加一层
pgrep -f 'nginx: master'验证主进程是否存在 - 对 Web 类服务,用
curl -sf http://localhost:80/health | grep -q "ok"更可靠 - 注意:某些服务(如
rsyslog)可能显示active但实际因配置错误未启动子进程
journalctl 查看服务异常的实用过滤技巧
直接 journalctl -u sshd 容易淹没在日志里,真正出问题时要快速定位失败上下文。
实操建议:
- 查最近一次启动失败:
journalctl -u nginx --since "1 hour ago" | grep -A 5 -B 5 "failed\|error\|exit code" - 按优先级过滤(只看 warning 及以上):
journalctl -u mysql -p 4(4=ERR,3=CRIT) - 结合时间戳定位重启点:
journalctl -u docker --since "2024-06-10 14:22:00" - 注意:默认 journal 存储在内存,重启后可能丢失;需确认
/etc/systemd/journald.conf中Storage=persistent已启用
systemd 服务状态码与 exit code 对照解析
服务退出时返回的 exit code 直接决定 systemctl show -p ExecMainStatus 的值,但不同服务约定不同,不能一概而论。
常见对应关系:
- code 0 → 正常退出(
ExecMainStatus=0) - code 1 → 通用错误(如配置加载失败,
nginx -t报错时常用) - code 2 → 无效参数(如
mysqld --help被误当服务启动) - code 203 → systemd 找不到可执行文件(
ExecStart=/usr/bin/nonexist) - code 226 → OOM killer 杀掉进程(查
dmesg -T | grep -i "killed process"确认)
关键点:仅看 ActiveState=failed 不够,必须结合 ExecMainCode 和 ExecMainStatus 判断根本原因。
用 systemctl show 提取结构化状态字段做监控集成
Zabbix、Prometheus 或自写巡检脚本若只依赖文本解析 systemctl status 输出,极易因格式变更崩掉。应改用 systemctl show 获取机器可读字段。
实操建议:
- 获取关键字段一行输出:
systemctl show nginx --property=ActiveState,SubState,ExecMainStatus,RestartCount - 解析 JSON 格式(需 systemd v246+):
systemctl show --property=StateChangeTimestamp --value nginx | date -d @$(echo "$_"/1000000 | bc -l) +%Y-%m-%d_%H:%M:%S - 监控项推荐采集:
ActiveState(active/inactive/failed)、RestartCount(防隐性崩溃重启)、MemoryCurrent(OOM 前兆) - 注意:
systemctl show默认输出所有属性,务必用--property=xxx限定,否则性能开销大且难解析
#!/bin/bash
# 示例:轻量服务健康检查函数
check_service() {
local svc=$1
systemctl is-active --quiet "$svc" || { echo "$svc inactive"; return 1; }
systemctl show "$svc" --property=ExecMainStatus --value 2>/dev/null | grep -q "^[0-9]\+$" || { echo "$svc main process gone"; return 2; }
[[ $(systemctl show "$svc" --property=RestartCount --value 2>/dev/null) -gt 3 ]] && echo "$svc restarted >3 times"
}
真实环境里,服务“看似正常”但请求超时、连接拒绝、日志静默才是最棘手的。别只盯 ActiveState,得把 ExecMainStatus、进程存在性、业务端口响应三者串起来看。










