一次完整的生产环境性能诊断案例:记录如何从测速结果惨败出发,逐步排查 GFW 干扰、PHP-FPM 并发模型、Laravel 缓存缺失等多个维度,最终找到真正的问题根源。
一、前置知识
阅读本文需要了解:
- Laravel 基础使用经验
- 宝塔面板基本操作
- 对 PHP-FPM、Nginx、Redis 有初步认知
本文涉及工具:
| 工具 | 用途 |
|---|---|
| 站长工具 | 全国多节点测速(高并发) |
| itdog | 全国多节点测速(支持低并发模式) |
| SSH + 宝塔面板 | 服务器诊断与操作 |
二、问题背景
服务器基本情况
- 服务器:香港 VPS(Ubuntu 24.04 LTS)
- 配置:1.9GB 内存,77G 磁盘
- 技术栈:Laravel 12 + Filament 4 + PHP 8.3 + Nginx + MySQL + Redis
- 访问域名:blog.gankudadiz.com
触发排查的现象
本地浏览器访问博客响应约 700ms,主观感受正常。但使用站长工具对博客域名进行全国测速后,结果触目惊心:大部分地区响应 5~10 秒,大量红色节点。
三、第一阶段:初步排查「是网络问题还是服务器问题?」
3.1 Ping 测试
首先对服务器 IP 和博客域名分别做 Ping 测试,排查网络层是否正常。
Ping 服务器 IP(x.x.x.x)

Ping 博客域名(blog.gankudadiz.com)

Ping 测试结果显示平均延迟约 42ms,说明网络层本身是通的,香港到大陆的路由质量尚可。
3.2 全国测速(站长工具)
使用 https://tool.chinaz.com/ 对博客首页进行全国多节点测速:

结果:绝大多数节点响应时间 5~10 秒,全红。
3.3 初步判断
Ping 快但 HTTP 慢,典型特征如下:
graph TD
A[用户请求] --> B{协议类型}
B -->|ICMP Ping| C[GFW 几乎不干预]
B -->|HTTP/HTTPS| D[深度包检测 DPI]
C --> E[42ms 正常]
D --> F[香港->大陆 QoS 限速]
F --> G[5~10s 超时]
初步怀疑:GFW 对香港到大陆的 HTTP 流量存在差异化处理。但这不是全部原因——还需要排查服务器本身的应用层配置。
四、第二阶段:服务器应用层诊断
通过 SSH 登录服务器,逐项检查生产环境配置。
4.1 诊断结果汇总
# SSH 连接命令
ssh -i "~/.ssh/id_ed25519" -p xxxx root@x.x.x.x
| 检查项 | 发现的问题 | 影响 |
|---|---|---|
| Laravel bootstrap/cache | 只有 packages.php 和 services.php,没有 config.php / routes.php | 每次请求重新解析配置和路由,增加 100~300ms |
| CACHE_DRIVER | .env 中未设置,默认使用 file(磁盘 I/O) |
Redis 装了白装,缓存走磁盘 |
| SESSION_DRIVER | database,每次请求查询 MySQL sessions 表 |
每次请求多一次数据库查询 |
| Redis | 8.0.4 运行正常,phpredis 扩展已安装 | 可用但未被利用 |
| PHP OPcache | 已启用,128MB | 正常 ✅ |
| Nginx gzip | 全局已开启,配置完整 | 正常 ✅ |
| Nginx JS/CSS 缓存 | expires 12h,时间偏短 |
用户频繁重新加载静态资源 |
4.2 关键问题:Redis 安装了但没用上
# .env 中的原始配置(问题版本)
APP_ENV=production
APP_DEBUG=false
SESSION_DRIVER=database # 每次请求查 MySQL
# CACHE_DRIVER 未设置 # 默认 file,走磁盘
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
每次 HTTP 请求的实际执行路径:
sequenceDiagram
participant 用户
participant Nginx
participant PHP-FPM
participant 磁盘
participant MySQL
用户->>Nginx: HTTP 请求
Nginx->>PHP-FPM: 转发
PHP-FPM->>磁盘: 读取路由缓存(不存在,重新解析)
PHP-FPM->>磁盘: 读取配置缓存(不存在,重新解析)
PHP-FPM->>MySQL: 查询 sessions 表(验证会话)
PHP-FPM->>磁盘: 读取 file 缓存
PHP-FPM->>Nginx: 返回响应
Nginx->>用户: 输出
五、第三阶段:执行优化
遵循「先备份后修改,先查看再操作」的生产环境原则。
5.1 备份关键文件
# 备份 .env
cp /www/wwwroot/gankudadiz_blog/.env \
/www/wwwroot/gankudadiz_blog/.env.backup.$(date +%Y%m%d%H%M%S)
# 备份 Nginx 站点配置
cp /www/server/panel/vhost/nginx/blog.gankudadiz.com.conf \
/www/server/panel/vhost/nginx/blog.gankudadiz.com.conf.backup.$(date +%Y%m%d%H%M%S)
5.2 修改一:启用 Redis 缓存和 Session
# 将 SESSION_DRIVER 改为 redis
sed -i 's/SESSION_DRIVER=database/SESSION_DRIVER=redis/' .env
# 在 REDIS_CLIENT 前插入 CACHE_DRIVER=redis
sed -i '/REDIS_CLIENT/i CACHE_DRIVER=redis' .env
修改后的关键配置:
CACHE_DRIVER=redis # 从 file 改为 redis
SESSION_DRIVER=redis # 从 database 改为 redis
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
5.3 修改二:生成 Laravel 全量生产缓存
cd /www/wwwroot/gankudadiz_blog
/www/server/php/83/bin/php artisan optimize
执行结果:
INFO Caching framework bootstrap, configuration, and metadata.
config ............................................... 171.57ms DONE
events ................................................. 1.86ms DONE
routes ............................................... 289.12ms DONE
views ..................................................... 24s DONE
blade-icons ........................................... 28.66ms DONE
filament .............................................. 41.17ms DONE
注意:views 缓存耗时 24 秒是正常的,因为 Filament 4 有大量 Blade 组件需要预编译。
5.4 修改三:延长静态资源缓存时间
# 将 JS/CSS 缓存从 12h 改为 30d
sed -i 's/expires 12h;/expires 30d;/' \
/www/server/panel/vhost/nginx/blog.gankudadiz.com.conf
# 验证修改
nginx -t && nginx -s reload
修改前后对比:
# 修改前
location ~ .*\.(js|css)?$ {
expires 12h; # 用户每 12 小时重新请求一次 CSS/JS
}
# 修改后
location ~ .*\.(js|css)?$ {
expires 30d; # 浏览器缓存 30 天,显著减少重复请求
}
5.5 验证所有修改
# 1. 确认 .env 配置
grep -E 'CACHE_DRIVER|SESSION_DRIVER' .env
# SESSION_DRIVER=redis
# CACHE_DRIVER=redis
# 2. 确认缓存文件已生成
ls /www/wwwroot/gankudadiz_blog/bootstrap/cache/
# blade-icons.php config.php events.php filament/
# packages.php routes-v7.php services.php
# 3. 确认 Nginx 缓存
grep 'expires' /www/server/panel/vhost/nginx/blog.gankudadiz.com.conf
# expires 30d;
六、第四阶段:发现真正的「并发瓶颈」——PHP-FPM 模式
6.1 新的排查思路
优化完成后,换用支持低并发检测的 itdog 重新测速,得到了截然不同的结果:
低并发检测结果(顺序请求):

快速检测结果(并发请求):

| 检测模式 | 平均响应 | 结果 |
|---|---|---|
| 低并发(顺序) | ~0.5s | 全绿 ✅ |
| 快速检测(并发) | 5~10s | 大量橙色 ❌ |
6.2 根本原因:pm = ondemand
查看 PHP-FPM 配置:
grep -E '^pm|^pm\.' /www/server/php/83/etc/php-fpm.conf
# 输出:
# pm = ondemand
# pm.max_children = 30
# pm.start_servers = 5 <- ondemand 模式下无效
# pm.min_spare_servers = 5 <- ondemand 模式下无效
# pm.max_spare_servers = 10 <- ondemand 模式下无效
ondemand 模式的工作机制:
sequenceDiagram
participant 测速工具
participant PHP-FPM
participant Laravel
Note over PHP-FPM: 平时无 worker 进程常驻
测速工具->>PHP-FPM: 并发 20 个请求同时到达
PHP-FPM->>PHP-FPM: 逐个创建 worker(耗时)
PHP-FPM->>Laravel: 加载框架初始化
Laravel-->>测速工具: 响应(5~10s)
Note over 测速工具: 低并发模式(顺序请求)
测速工具->>PHP-FPM: 请求 #1
PHP-FPM->>PHP-FPM: 创建 worker
Laravel-->>测速工具: 响应(0.5s)
Note over PHP-FPM: worker 保持存活
测速工具->>PHP-FPM: 请求 #2(复用已有 worker)
Laravel-->>测速工具: 响应(0.5s)✅
6.3 为什么不修改?
虽然找到了原因,但综合评估后决定保持 ondemand 不变:
- 站点访问量极低,几乎不会遇到真实并发场景
- 服务器还需部署其他低流量工具站,内存需要合理分配
ondemand模式平时零内存占用,对多站点共存最友好- 测速工具的并发场景是人为制造的,不代表真实用户体验
结论:测速工具的「并发分」不等于用户体验分。真实用户访问是低并发的,0.5s 的响应完全达标。
七、优化效果总结
本次变更清单
| 变更项 | 修改前 | 修改后 | 预期收益 |
|---|---|---|---|
| CACHE_DRIVER | file(磁盘) | redis(内存) | 缓存读写速度提升 10x+ |
| SESSION_DRIVER | database(MySQL 查询) | redis(内存) | 每请求减少一次 DB 查询 |
| Laravel 缓存 | 未生成 | config/routes/views 全量缓存 | 路由解析从 ~300ms 降至 0ms |
| Nginx 静态资源 | expires 12h | expires 30d | 用户二次访问几乎无 HTTP 请求 |
八、总结要点
核心收获
-
Ping 快不等于 HTTP 快:ICMP 与 HTTP 协议在 GFW 面前待遇不同,Ping 测试不能代表网页响应速度。
-
选对测速工具和测速模式:高并发测速适合评估高流量站点,对个人低流量博客没有参考价值。要选择匹配自己业务模型的测试方式,itdog 的低并发模式更接近真实场景。
-
Redis 装了要用上:很多宝塔环境装了 Redis 但
.env中未配置,白白浪费资源。检查CACHE_DRIVER和SESSION_DRIVER是生产环境优化的基础动作。 -
artisan optimize是部署必做项:每次git pull后都必须执行,否则路由/配置/视图缓存不更新,每次请求都要重新解析。 -
ondemandvsdynamic要看场景:低流量多站点用ondemand节省内存,高流量单站点用dynamic保持 worker 常驻,没有绝对好坏,适合自己的才是最好的。
每次部署 Checklist
cd /www/wwwroot/gankudadiz_blog
git pull
/www/server/php/83/bin/php /usr/bin/composer install --no-dev --optimize-autoloader
/www/server/php/83/bin/php artisan migrate --force
/www/server/php/83/bin/php artisan optimize:clear
/www/server/php/83/bin/php artisan optimize
/www/server/php/83/bin/php artisan queue:restart
参考工具:站长工具 chinaz | itdog 低并发测速
评论信息也没有自动保存哈
至于评论信息可能我平时工作做网站惯性思维了,我现阶段的逻辑是用户评论后我后台去审核,防止一些无用的评论,之后可以考虑直接通过审核的形式,感谢站长大大给出的意见。