深夜惊魂:网站突发502,PHP进程集体罢工的真相
凌晨2点17分,手机突然疯狂震动——监控报警!我负责的电商网站突然大面积502,后台显示所有PHP-FPM进程全部消失。作为经历过无数次深夜故障的老司机,这次的情况却让我头皮发麻…
一、故障现象:毫无征兆的集体阵亡
登录服务器后看到这样的场景:
$ systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled)
Active: failed (Result: timeout) since Thu 2023-05-18 02:15:32 CST
更诡异的是,重启服务后不到5分钟又会崩溃。查看/var/log/php-fpm.log
发现大量这样的记录:
WARNING: [pool www] seems busy (you may need to increase pm.start_servers)
二、抽丝剥茧:从磁盘空间突破
正当我准备调整PHP进程参数时,突然发现df -h
显示:
/dev/vda1 50G 50G 20K 100% /
好家伙,磁盘居然被塞满了!用du -sh /* | sort -rh
快速定位,发现/var/log
目录占用了惊人的47GB。
三、真相大白:失控的日志洪水
进一步检查发现,某个新上线的支付接口在疯狂写日志:
// 错误示范:未关闭的调试日志
$log->debug('支付请求参数:', $_REQUEST); // 包含整个$_REQUEST数组!
这个接口每分钟被调用2000+次,每次记录完整的请求数据(包含base64编码的图片),单个日志文件每小时就能涨到3GB!
四、止血与预防:我的组合拳
紧急处理:
- 用
truncate -s 0 /var/log/payment.log
清空日志文件(比rm更安全) - 临时增加
logrotate
配置,按小时切割日志
长期方案:
// 1. 敏感信息过滤
$log->debug('支付请求', [
'order_id' => $request['order_id'],
'amount' => $request['amount']
// 过滤掉$_REQUEST原始数据
]);
// 2. 生产环境关闭DEBUG日志
if (env('APP_ENV') === 'production') {
$log->setLevel(Logger::INFO);
}
五、经验总结
这次事故教会我三个道理:
- 永远要给系统盘留至少20%的缓冲空间
- 日志记录要遵循”最小必要”原则
- 新功能上线必须配套监控(我后来给日志目录加了磁盘空间报警)
现在回想起来,那天凌晨的咖啡格外苦涩——但正是这样的实战教训,让我们搭建的监控体系越来越完善。各位同行如果遇到类似问题,不妨先df -h
看一眼,说不定能省下几个小时的排查时间呢!
半夜修bug的苦程序员都懂,咖啡当水喝的日子太难了 😭
我们公司上次也是日志把磁盘撑爆了,现在监控直接显示磁盘使用率,再也不敢偷懒了
建议用ELK做日志收集,单机写文件太危险了
学到了!原来truncate比rm安全,之前都是直接删