站点一出问题,第一反应往往是加内存、换服务器、装个加速插件。但多数答案其实已经写在日志里了:谁在打你、哪个页面慢、错误集中在什么时段,日志都记着,只是没人翻。
这篇给三条命令,加上一套看懂结果的方法。不需要装任何面板,一台能 SSH 的服务器就够。

图片由 AI 生成
先看日志格式对不对
Nginx 默认的 combined 格式里没有耗时字段,光看它分析不出慢在哪。打开站点配置确认一下,日志格式里至少要有这两个变量:
$request_time:Nginx 从收到请求到发完响应的总耗时$upstream_response_time:后端(PHP、Node)处理花的时间
把它们放在日志行的末尾最方便,用 $NF 就能直接取到。改完格式记得 reload,旧日志还是老格式,分析时别混着看。
三条命令,先摸清基本盘
谁在打你
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
访问量前十的 IP。正常站点里,这个榜单应该是搜索引擎、CDN 回源和几个真实用户,如果冒出来一个单 IP 占比超过两成,基本可以确定是爬虫或者扫描器。
返回了什么
awk '{print $9}' access.log | sort | uniq -c | sort -rn
状态码分布。健康的站 200 占九成以上;404 突然变多,多半有人在探路径;302 扎堆,检查是不是跳转规则写错了;499 多,说明客户端等不及主动断开,通常意味着页面太慢。
哪里最慢
awk '{print $NF, $7}' access.log | sort -rn | head -20
取耗时最长的二十条请求。把路径归一下类,通常就那么两三个页面在拖后腿——要么是没走缓存的列表页,要么是带复杂查询的搜索页。

图片由 AI 生成
怎么判断是哪一种病
| 特征 | 大概率是什么 | 先做什么 |
|---|---|---|
| 单 IP 高频打 wp-login.php、xmlrpc.php、.env | 后台扫描 | Nginx 直接 403,上 fail2ban |
| 单个 UA 全站扫,路径分散,速度很快 | 爬虫或采集 | 看 robots 与 UA 规则,必要时限速 |
| 慢请求集中在少数 URL,upstream 时间高 | 后端或数据库慢 | 查慢查询、加缓存 |
| request_time 高但 upstream 低 | 网络或静态资源传输 | 开压缩、上 CDN |
| 502/504 集中在固定时段 | PHP-FPM 打满或上游超时 | 看 error.log 与进程数 |
| 图片请求 referer 大量来自外站 | 盗链 | 配防盗链,或图片走 CDN |
判断 request_time 和 upstream_response_time 的关系,是最有用的一条经验:两个数接近,问题在后端;总耗时高、上游时间低,问题在网络、TLS 或者静态文件传输。方向定错了,优化就是白费劲。
发现之后做什么
扫描类的,先在 Nginx 层拦住敏感路径,再用 fail2ban 按日志自动封 IP。规则别写太宽,误封搜索引擎会直接影响收录,改完规则先观察一天。
爬虫类的,先分清是搜索引擎还是采集。搜索引擎的 UA 可以反查验证,采集的通常是伪造 UA、频率极高。限速用 limit_req,阈值按正常用户的峰值定,别一刀切到把真实访客也挡住。
慢页面类的,优先加缓存,其次才是优化代码。一个列表页从 1.2 秒降到 0.2 秒,最省事的办法往往是页面缓存,而不是重写查询。
几个实用的小技巧
归档日志是 .gz 的,不用解压,直接 zcat access.log.2.gz | awk ... 就能读。日志太大跑不动,先按时间切一段出来再分析。
想看得更直观,装个 GoAccess,一条命令把日志转成 HTML 报表,Top URL、状态码、响应时间分布都有,适合每周固定看一次。
日志本身也别无限留。保留 14 到 30 天够用了,再长就压缩归档到别处,否则磁盘被日志写满,站点会以最莫名其妙的方式挂掉。
排查问题的顺序应该是:先看日志,再看配置,最后才动硬件。多数“服务器不够用”,其实是某个页面没缓存,或者某个 IP 在刷。
建议把这三条命令存成一个脚本,每周跑一次,输出存到文件里。站点正常的时候看不出价值,等哪天流量异常,翻出前几周的基线一对比,问题在哪儿一目了然。

