PHP架构师私藏调试心法:3行代码揪出90%线上故障
|
文章配图,仅供参考 去年春节值班那会儿,接口超时告警突然炸锅——监控大盘上那条绿色的线抖得跟帕金森似的,我盯着屏幕看了三秒,第一反应是“又他妈缓存击穿了”。结果翻日志发现,慢查询堆了二十多层,最底下那行根本刷不出来,键盘都快被我敲烂了也没滚动到底。这时候老张叼着牙签晃过来,说了句“试试那三行代码”,我当场就想骂人——这货上个月刚把定时任务写死,害得我们手动清了两天的脏数据。可当时也没别的招。我原以为得翻表结构、查索引、看慢查询日志,结果他让我直接在入口文件里塞了三行: register_shutdown_function(function(){ $error = error_get_last(); file_put_contents('/tmp/debug.log', json_encode($error), FILE_APPEND); }); 我盯着这段代码看了半天,心想这不就是个错误捕获吗?能顶什么用?老张叼着烟说:“你试试灰度10%流量,看/tmp/debug.log里有没有东西。”结果三分钟后,日志里蹦出来一堆“Maximum execution time of 30 seconds exceeded”——好家伙,原来是某个接口的SQL没走索引,全表扫描把PHP-FPM进程堵死了。 这事儿最邪门的是,同样的故障上个月刚发生过。当时运维说“可能是网络抖动”,产品说“用户侧反馈正常”,前端说“我的接口响应挺快啊”。最后我熬了两个通宵,把所有接口的QPS、耗时、错误率全导出来,才发现是某个隐藏字段的类型从INT改成VARCHAR后,索引失效了。那会儿我还觉得是自己太菜,没早点发现——现在想想,要是早用这三行代码,何至于被运维和产品轮流怼? 不过说真的,这三行代码能成“私藏心法”,靠的就是“优胜劣汰”。我之前试过用XHProf、Blackfire这些专业工具,结果配置半天不是报错就是数据不对,最后还得回滚代码。而这三行代码,不用改业务逻辑,不用装扩展,甚至不用重启服务——只要把文件往入口一扔,故障现场的“最后一口血”就能被逮住。就像上次那个幂等接口,用户重复提交导致订单状态混乱,我们翻遍日志都没找到原因,最后靠这三行代码抓到了“Undefined index”的错误——原来是某个中间件偷偷改了请求参数的结构。 当然,它也不是万能的。比如上个月遇到个慢查询雪崩,这三行代码只能告诉我“超时了”,但具体是哪条SQL、走了哪个索引、数据量多大,还是得靠慢查询日志。可问题是,线上环境谁敢随便开慢查询日志?一开就可能把磁盘撑爆,运维能追着你骂三天。这时候三行代码的优势就出来了——它只抓“致命错误”,不碰业务日志,运维就算再龟毛也挑不出毛病。 说到这儿,我突然想起工位隔断上贴的那张便签——那是去年双十一前写的“禁止修改订单表结构”,现在卷了边,字都快看不清了。当时我们刚上线新支付系统,产品非要在订单表里加个“促销类型”字段,结果测试环境没问题,线上一跑就报“Duplicate entry”。后来查了半天,发现是历史数据里有重复的促销ID,而新字段没加唯一索引。那会儿要是用了这三行代码,可能早就在/tmp/debug.log里看到“Duplicate entry”的错误了,也不用等到用户投诉才发现。 不过话说回来,这三行代码也不是没踩过坑。有次我把它塞进一个老项目的入口文件,结果发现/tmp/debug.log根本没生成——后来才知道,那个项目的PHP运行用户没有/tmp的写入权限。还有次,线上环境把/tmp挂载成了tmpfs,日志文件一大就被自动清理了,害得我白等了半小时。所以现在用之前,我都会先在测试环境跑一遍,确认日志能正常写入,再灰度到线上。 咖啡机坏了那天,我正用这三行代码排查一个接口超时问题。日志里显示“Allowed memory size exhausted”,我第一反应是“内存泄漏”,结果翻代码发现是某个循环里没做释放,导致每次请求都多占200M内存。那会儿运维在旁边打电话谈房租,声音大得我头都炸了,我直接冲他喊:“能不能小点声?我这儿正抓内存泄漏呢!”他白了我一眼:“你抓你的,我谈我的,互不干扰。”结果那通电话打了十分钟,我硬是靠这三行代码和top命令,把内存泄漏的代码段给定位了——最后发现是某个第三方SDK的缓存没清,每次请求都叠加。 现在想想,这三行代码能成“私藏心法”,可能就是因为它够“土”——不依赖任何框架,不挑PHP版本,甚至不关心业务逻辑。就像老张说的:“线上故障就像小偷,你越用高科技防盗,他越能找到漏洞;反而是这种最原始的‘守株待兔’,有时候能逮个正着。”当然,这话有点绝对,但至少在我们组,这三行代码已经成了排查故障的“第一反应”——比翻日志、看监控、查堆栈都快。 不过我也知道,它不是终极解决方案。比如遇到分布式锁失效、消息队列积压、缓存穿透这些问题,三行代码可能连错误都抓不到。但话说回来,线上90%的故障,不都是这种“低级错误”吗?索引没加、字段类型不对、内存没释放、权限没配置——这些事儿,专业工具可能查半天查不出来,而三行代码,三分钟就能给你个方向。所以有时候我在想,所谓“架构师的心法”,可能不是多复杂的算法或多高深的设计,而是能在最乱的环境里,用最简单的方法,抓住最关键的线索。 现在我的工位上,除了那张卷了边的便签,还贴了张纸条:“线上故障,先试三行。”有时候运维路过,会调侃一句:“又守株待兔呢?”我头也不抬地回:“兔子多,树少,不守白不守。”他笑笑走开,我继续盯着/tmp/debug.log——谁知道下一秒,会不会又蹦出个“致命错误”呢? (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


Linux系统线上故障排查的几种技巧