【每日一题】Linux 里统计 500 错误最多的 10 个接口(附参考答案)

题目:线上反馈某接口偶发 500。access.log 以空格分列,第 7 列是 URL、第 9 列是状态码。要统计状态码为 500 的请求按 URL 出现的次数,并取次数最多的前 10 个,下列命令最合理的是:

A. grep ' 500 ' access.log | sort | uniq -c | head 10
B. awk '$9==500 {print $7}' access.log | sort | uniq -c | sort -rn | head -10
C. awk '{if($9=500) print $7}' access.log | uniq -c | sort -n | top 10
D. grep 500 access.log | cut -d' ' -f7 | count | sort -k2 -r | head -10

难度:初级
题型:笔试(单选题)

:point_right:参考答案:B

解析:

  • A 错两处:grep ' 500 ' 会连带命中响应字节数、端口、时间里的 500,噪音极大;uniq -c 统计的是整行而不是 URL,同一接口每行时间戳都不同,数不出聚合结果;head 10 参数也不对(要 head -10 或 head -n 10)。
  • C 错三处:$9=500 是赋值不是比较(应写 ==,条件恒真,全量都被打印);uniq -c 前没有 sort,只合并相邻重复行;top 是进程监控命令,不是文本管道工具。
  • D 错两处:grep 500 同样命中体积字段;count 不是标准 Linux 命令,聚合还得靠 sort | uniq -c。

采分延伸(面试官接着问的通常是这些):

  1. 死规则:uniq -c 前面必须先 sort,这是最常考的一步。
  2. 按接口聚合要去掉 query:awk '$9==500 {gsub(/\?.*/,"",$7); print $7}',否则 /order?id=1、/order?id=2 会被算成两个接口。
  3. 看全部 5xx 用 awk '$9~/^5/' 或 $9>=500;只看某个时间段用 awk '$4 ~ /04\/Nov\/2026:10:/'。
  4. 轮转出去的日志一起捞:zcat access.log.*.gz | awk '$9==500 {print $7}' | sort | uniq -c | sort -rn | head。
  5. 实时盯:tail -f access.log | awk '$9==500';grep 配管道要加 --line-buffered,否则看不到即时输出。
  6. 大文件提速:LC_ALL=C sort 关掉 locale 排序;先用 awk 只输出一列再排序,比整行排序快很多。
  7. 数总行数不用聚合:grep -c 或 wc -l;grep -c 只数行,不能分组。
  8. 排查思路(性能向):500 要先看是集中在某接口还是全局,集中的看应用错误日志与堆栈,全局的看线程池打满、DB 连接耗尽、下游超时,配合 top -H、jstack、ss -s。