服务器站点访问慢如何逐层排查
学完这篇你能拿到一套按“客户端→DNS→链路→带宽→系统→Web 层→应用/数据库→日志”顺序执行的排查清单,照着敲命令就能把“慢在哪一层”定位出来。
第一步:先确认是不是只有你慢——查客户端和 DNS
这一步要排除你本地网络、浏览器缓存和 DNS 解析的问题,做完能知道慢是不是只发生在你这一台机器上。
打开 Chrome 或 Edge,按 F12,切到 Network 面板,刷新页面,点任意一个请求,看 Timing 标签。如果 DNS Lookup 很长,说明解析慢;如果 Waiting (TTFB) 很长,说明服务器处理慢。
再用 curl 拆时间:
curl -o /dev/null -s -w "DNS:%{time_namelookup} TCP:%{time_connect} SSL:%{time_appconnect} TTFB:%{time_starttransfer} TOTAL:%{time_total}\n" https://example.com
正常情况 DNS 几十毫秒、TCP 几十毫秒、TTFB 几百毫秒。如果 DNS 超过 500ms,用 dig example.com +trace 看是哪一级 DNS 慢。
注意:curl 默认走本机 DNS 缓存,测不同解析结果时加
--resolve example.com:443:1.2.3.4强制指定 IP。
第二步:测网络链路,看丢包和延迟在哪一跳
这一步要判断问题出在你到机房之间的哪一段,做完能区分是本地运营商、骨干网还是机房入口的问题。
Ubuntu 22.04 先装 mtr-tiny:
sudo apt update && sudo apt install -y mtr-tiny
mtr -rwzc 20 example.com
CentOS 7 用 yum install -y mtr。看 Loss% 和 Avg 两列,某一跳开始丢包且后续持续丢,问题就在那一跳之后。
如果用 ICMP 被限速,改用 TCP 模式:
mtr -rwzc 20 -T -P 443 example.com
注意:中间某跳显示 100% 丢包但最后一跳正常,通常是该路由器不响应 ICMP,不代表故障。
第三步:查服务器入口带宽和云监控
这一步要看服务器出口带宽是否被打满,做完能排除“带宽跑满导致所有请求变慢”。
以阿里云为例:登录 ECS 控制台 → 左侧 实例与镜像 → 实例 → 选中目标实例 → 上方 监控 标签 → 操作系统监控,重点看 公网出带宽、CPU 使用率、内存使用率。腾讯云路径是 云服务器 → 实例 → 选中实例 → 监控。
服务器里也可以直接看:
sar -n DEV 1 5
看 txkB/s 是否接近带宽上限。再装 iftop:
sudo apt install -y iftop && sudo iftop -i eth0
注意:云厂商的公网带宽是“出带宽”限制,入带宽通常不限,别只看入方向。
第四步:登录服务器看整体负载
这一步要确认 CPU、内存、磁盘 IO 是否成为瓶颈,做完能知道系统层是不是已经过载。
ssh user@your-server
top
uptime
vmstat 1 5
iostat -x 1 5
uptime 看 load average,如果 1 分钟值远大于 CPU 核数就要警惕。vmstat 看 %wa,超过 20 说明磁盘 IO 等待严重。iostat -x 看 %util,接近 100% 说明磁盘跑满。
注意:load 高不等于 CPU 忙,可能是 IO 等待或大量进程排队,要结合
%wa和%id一起看。
第五步:检查 Nginx 或 Apache 这一层
这一步要区分慢在 Nginx 本身还是后端应用,做完能锁定是“前端代理慢”还是“后端接口慢”。
Nginx 1.24 先看配置:
nginx -T
再看访问日志。确认 nginx.conf 的 log_format 里加了这两个变量:
log_format main '$remote_addr - $request_time $upstream_response_time "$request"';
然后实时看:
tail -f /var/log/nginx/access.log
$request_time 是 Nginx 总耗时,$upstream_response_time 是后端耗时。如果前者大、后者小,慢在 Nginx 到客户端之间;如果后者大,慢在后端。
Apache 2.4 用 apachectl status 看当前连接和请求数。
注意:
$upstream_response_time可能显示多个值,用逗号分隔,表示多次重试或子请求,取最后一个看最终后端耗时。
第六步:查后端应用和数据库
这一步要定位到具体是 PHP、Java 还是 MySQL 拖慢了响应,做完能拿到慢查询或慢方法。
PHP-FPM 开慢日志:在 php-fpm.conf 里设 request_slowlog_timeout = 5s 和 slowlog = /var/log/php-fpm/slow.log,重启后看慢日志。
Java 用 jstack <pid> 抓线程栈,看是不是大量线程卡在数据库等待。
MySQL 8.0 开慢查询:
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SHOW FULL PROCESSLIST;
看 Time 列,超过几秒的 SQL 就是嫌疑对象。
注意:数据库慢查询会占住连接池,表现成 Nginx
upstream timed out,别只重启 Nginx 不查数据库。
第七步:按时间戳对齐各层日志,复现并确认根因
这一步要把 Nginx、应用、数据库三份日志按同一时间点对齐,做完能确认根因并验证修复效果。
用 grep 过滤同一分钟:
grep "10:23:1" /var/log/nginx/access.log
grep "10:23:1" /var/log/app/app.log
看同一秒有多少并发请求,再对比数据库慢日志的时间点。
注意:不要只看单条慢请求,要看同一秒的并发量,很多“慢”其实是瞬时并发把连接池打满。
小结
- 排查顺序:客户端/DNS → 网络链路 → 云监控带宽 → 系统负载 → Nginx/Apache → 应用/数据库 → 日志对齐。
- 关键命令:
curl -w拆时间、mtr -T -P 443测链路、top/vmstat/iostat看系统、nginx -T看配置、access.log看$request_time和$upstream_response_time、MySQL 慢查询日志。 - 核心判断:
$request_time大而$upstream_response_time小,慢在前端;反过来慢在后端。 - 最后一定要按时间戳对齐多层日志,避免只凭单条日志下结论。
原文链接:https://www.gj0.com/thread-709.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。