上一篇 下一篇 分享链接 返回 返回顶部

最新Ubuntu上的宝塔WordPress访问变慢,如何从DNS、服务器负载到应用响应分层排查?

发布人:Minchunlin 发布时间:2026-10-02 20:44 阅读量:3

在最新的Ubuntu系统上安装宝塔和wordpress后首次上线,页面却比迁移前慢,最容易出现的误判是直接重装宝塔、切换 PHP 版本或盲目更换服务器。一次 HTTPS 请求会依次经过本地网络、DNS 解析、TCP 建连、TLS 握手、路由传输、Nginx、PHP-FPM、WordPress、数据库以及页面资源加载,任一环节等待,都可能被浏览器概括成“网站打开慢”。

开篇:从请求链路理解“网站打开慢”配图

排查应先用同一个网址建立基线,再按“客户端与源站对比 → DNS → 路由和丢包 → 服务器负载 → Nginx、PHP-FPM、数据库和 WordPress”的顺序向内收敛。只有当某一层的时间或错误与慢请求同时出现时,才修改对应配置;修复后还要用相同请求再次验证,避免同时改动多个因素而无法判断效果。

先用时间指标确定慢在哪一段

先在访问端连续请求 3 至 5 次,替换实际域名:

for i in $(seq 1 5); do
  curl -sS -o /dev/null \
    -w "code=%{http_code} dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s remote=%{remote_ip}\n" \
    "https://www.example.com/"
done

这些数值是累计时间,不能都当成独立阶段的耗时。可以按下面方式理解:

  • DNS 阶段约为 time_namelookup;
  • TCP 建连阶段约为 time_connect - time_namelookup;
  • TLS 握手阶段约为 time_appconnect - time_connect;
  • 从 TLS 完成到收到首字节的等待,约为 time_starttransfer - time_appconnect;
  • 收到首字节后的下载阶段,约为 time_total - time_starttransfer。

如果访问的是 HTTP 而不是 HTTPS,TLS 阶段不适用。ttfb 是从请求开始到收到首字节的累计时间,通常包含 DNS、连接和服务端处理等待,不能简单等同于 PHP 执行时间。

可以先建立这样的判断:

现象优先检查方向不宜立即做的事
dns 偶尔达到数秒,其他阶段正常DNS 记录、解析缓存、A/AAAA 地址不要先调 PHP-FPM
TCP 阶段波动大,或连接经常超时本地网络、路由、丢包和端口可达性不要只凭中间路由一跳判断故障
连接很快,但 ttfb 持续偏高Nginx、PHP-FPM、数据库、WordPress不要反复清理本地 DNS 缓存
ttfb 很快但 total 很长图片、脚本、样式表和第三方资源不要先增加 PHP-FPM 进程数
状态码出现 502、503、504上游服务、资源耗尽或配置错误不要批量重启所有 PHP 版本

浏览器开发者工具的 Network 面板可以作为第二组证据。若 DNS 阶段长,优先查解析;若 Connecting 阶段长,查网络和路由;若 SSL 阶段长,查连接稳定性和证书链;若 Waiting for server response 长,转向源站和应用。首字节已经很快、页面仍迟迟不完整时,重点应放在资源瀑布图,而不是继续调整 PHP。

“最新 Ubuntu”不是一个固定版本名称。先确认实际系统和运行服务,避免照搬不匹配的服务名:

cat /etc/os-release
uname -a
hostnamectl

systemctl list-units --type=service --state=running | \
  grep -Ei 'nginx|apache2|php.*fpm|mysql|mariadb'

同时记录站点是否使用 HTTPS、宝塔中实际选择的 Web 服务、PHP 版本、数据库服务和页面缓存状态。不要直接假定服务一定叫 php8.1-fpm、mysql 或 nginx,Ubuntu 版本、宝塔安装方式和 PHP 多版本共存情况都可能使服务名不同。

第一个分支:访问链路慢,还是源站响应慢

在访问端执行一次基线请求后,再登录源站执行相同请求:

curl -sS -o /dev/null \
  -w "code=%{http_code} connect=%{time_connect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/"

这次对比不是绝对的“应用纯耗时”,因为源站执行时仍可能经过自身 DNS、网卡和对外地址;它的价值在于判断访问端到服务器之间是否额外增加了明显等待。

  • 访问端慢,而源站执行同一网址很快:优先检查本地网络、DNS、路由、丢包或客户端到服务器之间的连接。
  • 访问端和源站执行时的 ttfb 都高:更接近 Nginx、PHP-FPM、数据库或 WordPress 处理问题。
  • 两端 ttfb 都快,但浏览器页面显示慢:检查页面资源数量、资源体积、缓存命中和第三方请求。
  • 只有后台慢、首页正常:重点检查后台插件、管理页面查询、定时任务和数据库。

如果怀疑 DNS,可用 --resolve 在不改变公网 DNS 的情况下指定地址。下面的 IP 只是文档示例,必须替换成实际 A 记录对应的地址:

curl -sS -o /dev/null \
  --resolve www.example.com:443:203.0.113.10 \
  -w "code=%{http_code} dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/"

该命令仍使用原域名发送 HTTPS 请求,因此可以保留域名匹配和证书校验逻辑。如果正常访问明显变慢,而 --resolve 的连接或首字节时间恢复,优先排查 DNS 返回的地址、解析缓存或多条记录之间的不一致。如果两种请求的 ttfb 都高,DNS 通常不是主要瓶颈。

DNS 正常后,再看路由和丢包

先核对 A、AAAA 记录以及当前机器的解析结果:

dig www.example.com A +noall +answer
dig www.example.com AAAA +noall +answer
resolvectl query www.example.com
getent ahosts www.example.com

如果系统没有安装 dig,可先使用 resolvectl 和 getent,不要为了排查一次慢请求就修改系统解析器配置。

重点确认三件事:

  1. A 记录是否指向当前宝塔服务器的公网 IP。旧服务器、测试地址或错误 IP 可能造成不同请求落到不同主机。
  2. 是否存在并不打算使用的 AAAA 记录。部分客户端会优先尝试 IPv6,如果服务器没有正确监听 IPv6 或 IPv6 路径不稳定,就可能出现部分网络慢、部分网络正常。
  3. 多条 A 或 AAAA 记录是否都能正常提供站点。只要其中一个地址不可用,用户就可能间歇性超时。

检查 80 和 443 端口的监听情况:

sudo ss -lntp | grep -E ':(80|443)\s'

若 DNS 发布了 AAAA,但服务器实际只有 IPv4 监听,应确认这是有意配置还是遗留记录。可选择正确配置并验证 IPv6,或在确认站点不使用 IPv6 的前提下移除 AAAA。修改 DNS 前保存原记录值和 TTL,修改后用 dig 复核,并保留恢复原记录的回滚方案。DNS 缓存不会同时在所有客户端更新,不能只根据一台电脑的结果判断变更已经完全生效。

本机解析缓存异常时,可以在 Ubuntu 客户端执行:

resolvectl flush-caches

该命令只清理本机缓存,不会修改公网 DNS,也不能修复错误的 A 或 AAAA。清理后重新执行 resolvectl query 和 curl:只有本机恢复,说明问题可能在本地缓存;多个访问环境都慢,则继续排查路由和源站。

DNS 记录正常后,再测试网络稳定性:

ping -c 20 www.example.com

ping 只能作为辅助证据。服务器或中间设备可能限制 ICMP,所以 ping 无响应不等于 HTTPS 一定不可用。关注的是持续丢包、延迟明显波动和最终目标是否异常:

  • 延迟稳定但数值略高,可能只是正常的网络距离差异;
  • 延迟偶尔突然升高,关注本地无线网络、出口拥塞或链路抖动;
  • 最终目标持续丢包,比某一次延迟偏高更值得优先处理;
  • 只有某个中间节点显示丢包,而后续节点和最终目标正常,常见于该节点降低 ICMP 响应优先级,不能据此认定业务数据包也在丢失。

系统已安装 mtr 时,可以持续观察完整路径:

mtr -rwzc 50 www.example.com

重点看最终目标一行,以及从哪一跳开始,后续节点是否持续出现丢包。如果只有中间某一跳偶发丢包、后续恢复正常,不要据此修改 Ubuntu 网络参数。也可以对解析出的实际 IP 做对照:

ping -c 20 203.0.113.10

如果域名访问异常、直接 IP 对照正常,回到 DNS 和地址选择问题;如果直接 IP 也持续高延迟或丢包,而源站本机请求稳定,应先保留服务器应用配置,继续确认访问端网络和到服务器之间的链路。丢包比例即使看起来不高,也可能造成 TCP 重传,使 HTTPS 建连、首字节或大文件下载变慢。

第二个分支:链路稳定后,检查 Ubuntu 主机和服务

确认 DNS、连接和最终目标没有明显异常后,再查看源站资源。以下命令只读取状态,不会重启服务或修改配置:

uptime
nproc
free -h
vmstat 1 5
df -hT
df -ih

ps -eo pid,ppid,comm,%cpu,%mem --sort=-%cpu | head -n 15

uptime 中的 load average 要结合 nproc 和 vmstat 判断。负载高于 CPU 核数,表示运行队列或等待增加,但不能单独证明 CPU 已经跑满:

  • us、sy 长时间较高,可能是 PHP、数据库或其他进程消耗 CPU;
  • wa 较高,更像磁盘 I/O 等待,应检查数据库、日志和磁盘状态;
  • si、so 持续出现,说明发生交换,内存压力可能已经影响 PHP 和数据库;
  • r 持续明显高于 CPU 核数,说明运行队列较长;
  • 磁盘空间或 inode 接近耗尽,日志、缓存和临时文件可能出现异常。

如果服务器负载高,同时源站本机请求的 ttfb 也高,先找出对应进程和发生时间,不要直接强制结束进程。宝塔监控曲线适合查看趋势,但应使用 SSH 命令核对当前状态,因为面板图表通常是采样数据,可能不能代表瞬时值。

确认服务名后,再查看实际服务状态。例如只有命令结果显示 nginx.service 时,才使用:

sudo systemctl status nginx --no-pager

需要查看 PHP-FPM、Nginx 或数据库时,同样先从 systemctl list-units 的结果中取得准确服务名。PHP CLI 版本也不一定等于网站实际使用的 FPM 版本:

php -v
php -m | grep -i opcache
ps -eo pid,cmd | grep '[p]hp-fpm'

如果只是修改了 Nginx 配置,先检查语法,再进行平滑重载:

sudo nginx -t
sudo systemctl reload nginx

reload 仍属于生产变更。操作前备份配置、记录修改内容并避开高峰;如果之后出现 502、连接异常或站点打不开,先恢复备份配置,再重新执行 nginx -t,确认无误后加载。不要因为页面慢就重启所有 PHP 版本的服务,这会扩大影响范围。

第三个分支:静态文件快、动态请求慢时,进入应用层

可以把首页、后台、接口和静态文件分开测试。后台未登录时可能只返回登录页或发生重定向,因此不能把未登录结果当作登录后的真实后台性能。

curl -sS -o /dev/null \
  -w "home code=%{http_code} ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/"

curl -sS -o /dev/null \
  -w "admin code=%{http_code} ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/wp-admin/"

curl -sS -o /dev/null \
  -w "api code=%{http_code} ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/wp-json/"

静态文件应替换成站点中确实存在并返回 200 的图片或 CSS 文件:

curl -sS -o /dev/null \
  -w "static code=%{http_code} ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
  "https://www.example.com/wp-content/uploads/实际文件名.jpg"

结果可以这样分支:

  • 静态文件、首页和接口都慢:回到网络、Nginx、磁盘和服务器负载;
  • 静态文件快,但首页和接口慢:重点检查 PHP-FPM、数据库、缓存和插件;
  • 首页快、后台慢:重点检查后台插件、管理页面查询、定时任务和数据库索引;
  • 第一次访问慢,后续明显变快:可能与页面缓存、OPcache、数据库缓存或服务预热有关;
  • 每次动态请求都慢:更像 PHP、数据库、外部接口等待或持续资源不足;
  • ttfb 快但 total 长:服务端已经开始返回,应检查图片体积、脚本、样式表和浏览器瀑布图。

先查看 Nginx 生效配置中的日志和 FastCGI 入口:

sudo nginx -T 2>/dev/null | grep -E 'access_log|error_log|fastcgi_pass'

宝塔站点日志路径会因站点配置和安装方式不同而变化,应以实际配置为准。找到路径后再查看最近记录:

sudo tail -n 100 /实际日志路径/access.log
sudo tail -n 100 /实际日志路径/error.log

如果日志格式包含请求耗时或上游响应耗时,可按以下方式判断:

  • Nginx 请求总耗时高、上游耗时低:检查响应体大小、静态资源或 Nginx 配置;
  • 上游响应耗时高:继续检查 PHP-FPM、WordPress 和数据库;
  • 大量 502:检查 PHP-FPM 是否退出、监听 socket 是否一致、进程是否耗尽;
  • 大量 499:客户端提前断开,可能是用户等待超时,也可能是网络不稳定;
  • 5xx 集中出现:按同一时间段查看 Nginx、PHP-FPM 和数据库日志,不要只看 WordPress 页面提示。

PHP-FPM 进程全部占满时,新请求会排队,CPU 不一定很高,但动态页面的 ttfb 会增加。应先核对池配置中的 pm.max_children、单个进程内存和请求峰值,再决定是否调整。不能因为当前数值偏小就直接调大;进程数增加会同步增加内存压力,可能导致交换、502 或服务崩溃。修改前备份配置、记录原值,修改后只重载实际使用的 FPM 服务,并验证首页、后台和错误日志。出现内存持续上涨、502 或交换增加时,恢复原值并重新加载。

数据库服务也要先确认实际名称:

systemctl list-units --type=service --all | grep -Ei 'mysql|mariadb'

如果系统提供 mysqladmin,可以进行存活检查:

mysqladmin ping

该命令因账号权限、认证方式或 socket 配置不同而失败时,不应仅凭失败结果认定数据库宕机。需要查看活动连接或慢查询时,使用具备相应权限的数据库账号,并避免把密码直接写在命令行中。生产环境不要为了短暂慢请求长期开启高开销的全量查询日志,优先查看已有慢查询记录、数据库 CPU、内存、磁盘等待和连接数。

如果 WordPress 或插件调用外部接口,接口超时、DNS 解析失败或连接失败也会拉长 PHP 响应时间。可从 PHP、WordPress 或插件日志中查找对应时间点的超时记录。停用插件会改变生产站点行为,操作前备份文件和数据库,记录原启用状态;验证失败时按记录恢复,不要批量停用后再凭记忆回滚。

页面缓存只能减少部分动态请求,不能修复 DNS、丢包、错误 AAAA 或源站连接问题。如果未缓存页面慢而缓存页面快,应先确认缓存命中情况和失效规则;如果动态源站响应本身已经很快,则没有必要继续增加 PHP-FPM 进程数。

按匹配结果处理,修复后用同一方法复核

发现 A 记录错误、AAAA 不可用或解析结果不一致时,才修改 DNS。保存原记录和 TTL,调整后用 dig 验证,再从同一客户端重复 curl;速度没有改善就恢复原记录,继续排查路由和源站,不要同时修改 PHP、Nginx 和 DNS。

发现最终目标持续丢包,而源站本机请求稳定时,先保留服务器配置,记录测试时间、目标 IP、丢包比例和访问环境。只有某个中间节点丢包、最终目标正常时,不要据此改服务器网络参数。

发现 vmstat 显示交换、I/O 等待或运行队列过高时,先定位进程和发生时间。可以先减少不必要的并发任务、确认日志是否异常增长、检查磁盘空间,再决定是否调整服务参数。涉及配置重载、PHP-FPM 参数或 Nginx 变更时,先备份并保留回滚值。

只有网络、DNS 和主机资源都正常,且问题集中在动态页面时,才进入 WordPress 的缓存、插件、主题代码、数据库慢查询和定时任务。每次只调整一个因素,并使用同一 URL、同一客户端和同一测试方式重复验证。

修复后的验证至少包括:

  1. 连续请求 3 至 5 次,比较 dns、TCP 阶段、ttfb 和 total 是否稳定;
  2. 同时测试首页、一个已确认存在的静态文件、后台入口和动态接口;
  3. 检查状态码,确认没有新增 301、302、502、503 或 504;
  4. 查看 Nginx、PHP-FPM 和数据库日志,确认错误没有持续增加;
  5. 用浏览器 Network 瀑布图确认原先耗时最长的阶段已经缩短;
  6. 如果修改过 DNS,结合 TTL 等待缓存更新后再次测试;如果修改过 Nginx 或 PHP 配置,保留原文件和回滚记录。

最终的选择路径很明确:DNS 时间高,查解析记录和地址;TCP 阶段高且最终目标持续丢包,查本地网络与访问链路;连接正常但首字节时间高,查服务器负载、PHP-FPM、数据库和 WordPress;首字节快而完整加载慢,则转向页面资源。只有静态与动态请求的结果都相互印证后,才适合继续调整宝塔中的服务参数。

按匹配结果处理,修复后用同一方法复核配图

目录结构
全文