systemctl本身不定义“健康”,只管理生命周期状态;所谓健康需分层判断:基础层查systemd状态(如is-active、list-units --state=failed),网络层查端口监听(ss -tln),业务层查响应(curl或mysql命令),亚健康层查近期日志错误。

直接用 systemctl 查“所有服务的健康状态”并不现实——systemd 本身不定义“健康”,只管理服务的生命周期状态(如 active、inactive、failed)。所谓“健康”,需要结合进程状态、端口监听、业务响应三方面综合判断。下面给出实用、分层、可落地的检查方式。
查服务当前 systemd 状态(基础层)
这是最可靠的起点,避免用 ps 或 pidof 误判:
-
systemctl is-active --quiet 服务名 && echo "running" || echo "not running"—— 脚本中推荐用此方式,靠退出码判断,不依赖字符串解析 -
systemctl list-units --type=service --state=failed—— 快速揪出已崩溃的服务 -
systemctl list-units --type=service --state=activating,deactivating—— 找出卡在启动/停止过程中的服务(常因超时或依赖未就绪)
查端口是否真正就绪(网络层)
仅 is-active 为 active 不代表服务能收请求。例如 Nginx 启动成功但配置错误,可能不监听 80 端口:
-
ss -tln | grep ':80'—— 检查 TCP 端口是否处于 LISTEN 状态(-tTCP,-llistening,-n数字端口) -
timeout 3 ss -tln | grep ':3306' && echo "MySQL port up"—— 加timeout防卡死,尤其在高负载或容器命名空间异常时 - 注意:某些服务(如 Redis)默认只监听本地,需确认绑定地址是否含
127.0.0.1或0.0.0.0
查服务是否返回有效响应(业务层)
端口通 ≠ 服务可用。HTTP 服务可能返回 502、503 或空响应,数据库连接池可能耗尽:
-
curl -f -s -o /dev/null -w '%{http_code}' --connect-timeout 3 --max-time 5 http://localhost:8080/health—— 返回200才算通过;-f让非 2xx/3xx 返回非零退出码 - 避免用
-I(HEAD 请求),部分服务对 HEAD 返回 405,但 GET 正常,会误报 - 非 HTTP 服务可改用对应协议探测:如用
mysql -h127.0.0.1 -P3306 -uuser -ppass -e "SELECT 1",同样要加timeout
查日志中近期错误(亚健康识别)
很多服务“活着”,但每分钟都在报错,属于典型亚健康:
-
journalctl -u nginx --since "30 minutes ago" | grep -i "error\|fail\|timeout" | tail -n 5—— 只扫最近半小时,避免全量日志阻塞 -
journalctl -u sshd --since "1 hour ago" | grep "Failed password" | wc -l—— 统计暴力破解尝试次数 - 重点看
Result:字段(如start-limit、resources),它们比Active: failed更早暴露根因











