crit级别记录Nginx进程级致命故障(如worker崩溃、fork失败、端口被占),标志服务已不可靠;error记录可重试的运行时错误(如超时、SSL失败),服务仍可继续运行。

crit 级别不是“更详细的错误”,而是“服务已不可靠”的信号灯——它只在 worker 进程崩溃、内存分配彻底失败、监听套接字被意外关闭等真实危急时刻写入。日常高并发下,它几乎不触发;一旦出现,必须立刻响应。
crit 日志到底记录什么,和 error 有什么本质区别
error 级别会记:上游连接超时、SSL 握手失败、rewrite 循环、磁盘满导致 access_log 写入失败……这些大多可重试或降级。crit 级别只记:worker process <pid> exited on signal Segmentation fault (11)</pid>、fork() failed while spawning "worker" process、bind() to 0.0.0.0:80 failed (98: Address already in use) 这类直接让 Nginx 失去服务能力的事件。
关键差异在于恢复能力:error 出现后请求可能失败但服务仍在;crit 出现后至少一个 worker 已退出,QPS 会突降,连接队列堆积,用户开始感知卡顿甚至 502。
常见误判点:
- 把
connect() failed (111: Connection refused)当 crit —— 它只是 error,说明 upstream 暂不可达,Nginx 会自动重试或切到 backup - 在配置里写
error_log /path/log crit;却指望看到 PHP 或应用层崩溃日志 —— crit 是 Nginx 自身进程级的生死线,不穿透到 upstream - 用
grep "crit" /var/log/nginx/error.log扫描,却忽略时间窗口 —— crit 事件往往伴随大量重复 error 日志(如 upstream 不可用引发的连锁报错),需结合前后 30 秒日志看上下文
如何确认 crit 日志真的生效且没被吞掉
Nginx 默认不记录 crit,必须显式声明级别,且依赖系统资源是否允许写入。验证三步:
- 检查编译参数:
nginx -V 2>&1 | grep -o with-debug不需要 —— crit 不依赖--with-debug,只要版本 ≥ 1.7.5 就支持 - 确认配置位置正确:
error_log必须放在main块(全局)或http块,不能只放在某个server或location里 —— crit 是进程级事件,作用域太小会丢失 - 手动触发一次测试(仅限测试环境):
kill -SEGV $(pgrep -f "nginx: worker"),然后tail -n 20 /var/log/nginx/error.log应立刻出现包含Segmentation fault和crit的行;若无输出,检查磁盘空间、日志路径权限(worker 进程 uid 必须有写权限)、SELinux 是否拦截
海量并发下 crit 日志的监控与响应要点
crit 日志量极少,但每条都代表一次服务损伤。不能靠定时扫描,要实时捕获:
- 用
inotifywait -m -e modify /var/log/nginx/error.log | while read _; do grep -q "crit" /var/log/nginx/error.log && echo "$(date): CRIT DETECTED" | mail -s "NGINX CRIT ALERT" ops@example.com; done—— 简单有效,避免轮询开销 - 不要只告警,同步执行诊断脚本:
ps aux | grep nginx看 worker 数是否减少、ss -tuln | grep :80看端口是否仍监听、dmesg -T | tail -20查内核 OOM killer 是否干掉了 worker - 注意日志竞争:多个 worker 同时 crash 可能导致多条 crit 写入同一行或覆盖,建议用
error_log syslog:server=unix:/dev/log crit;推给 journald,它自带原子写和序列号 - 生产环境禁用
debug或info级别,但可以临时对单个 worker 提升日志粒度:kill -USR2 <worker_pid></worker_pid>(部分版本支持),比全局 reload 更精准
真正难的不是看到 crit,而是区分它是偶发抖动(如某次 fork 失败后自动恢复)还是雪崩前兆(连续 3 分钟内出现 5+ 次)。这时候必须交叉比对系统指标:CPU 软中断是否飙升、/proc/meminfo 中 Committed_AS 是否逼近 CommitLimit、dmesg 里是否有 Out of memory: Kill process —— crit 是症状,不是病因。

















