PHP调试总卡壳?3步精准定位90%技术隐藏Bug
|
去年过年时,服务器在初四凌晨三点十七分吐出第一个502——就那种白底黑字、没图标、连“稍后再试”都不配有的纯HTTP错误页。我叼着半截没点的烟蹲在工位上刷日志,同事老张隔着隔板喊:“你那PHP是不是又偷偷加载了GD库?”我回他:“GD早卸了。”他哦一声,转身去泡面,塑料叉子刮碗底的声音特别响。 查nginx access日志,请求全卡在upstream timeout;翻PHP-FPM慢日志,第八次看到同一行:`script '/var/www/html/api/v3/user.php' timed out after 30 seconds`。我原以为是DB锁表,结果mysqladmin processlist里连个sleep进程都没有;我原以为是curl超时,抓包一看——根本没发出请求。它就卡在PHP执行层,像被谁按住了呼吸阀。 于是开三个终端窗口:左边tail -f php-fpm.log,中间strace -p `pidof php-fpm | cut -d' ' -f1`,右边php -d display_errors=1 -d error_reporting=-1 /var/www/html/api/v3/user.php。前二十分钟什么也没发生,直到老张端着面碗晃过来,勺子碰碗沿当啷一响,我手一抖按了Ctrl+C,strace输出停在半截系统调用里:`openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = ?`——后面是个未完成的问号,不是数字,不是-1,就是个问号。 我盯着那个问号看了六秒,忽然想起三天前运维小陈说:“哎,证书链更新了,你们PHP不走系统CA吧?”我回:“走啊,file_get_contents默认走的。”他点头走了。我也不知道他点的哪次头,反正我信了。结果现在strace卡在openat这,而/etc/ssl/certs/ca-certificates.crt文件权限是600,属主root:root。PHP-FPM跑在www-data用户下。它连打开都做不到,更别说读取——但PHP不报Warning,不抛Exception,不记录error_log,就默默hang住,等timeout,然后nginx给个502。 改权限?不行。改配置加openssl.cafile?太晚了——当时php.ini里那行是注释掉的。最后我直接在脚本开头硬塞了一句:`stream_context_set_default(['ssl' => ['cafile' => '/etc/ssl/certs/ca-bundle.crt']]);`——那是个软链接,指向同目录下另一个世界权限宽松的bundle。页面刷出来了,灰绿色背景,用户头像正常加载,接口返回200。可我点开Chrome开发者工具Network面板,发现Authorization header莫名其妙少了一个空格,导致JWT校验失败——这事跟证书一点关系没有,纯粹是我复制token时多按了一次Backspace。反正我没修它。 (窗台上那盆绿萝去年枯死过两次,第二次我换土时发现盆底钻出细白根须,缠着排水孔,像一小截旧数据线)
文章配图,仅供参考 我后来把strace那行命令记死了,每次502第一反应不是看PHP代码,而是盯住它卡在哪次系统调用。不是所有超时都该归罪于逻辑,有些就是权限漏了、符号链接断了、甚至/dev/random被某个服务占着不肯放。老张昨天问我:“现在还卡吗?”我说:“不卡了,卡得更准了。”他嚼着花生米点头,花生碎掉在键盘F键缝隙里,积了灰。可我现在想起来——年初那次502,到底是因为证书路径不可读,还是因为PHP-FPM子进程用了共享的SSL_CTX句柄,导致初始化阻塞在全局锁上?我也不知道。有谁碰到过这个吗 (编辑:航空爱好网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


PHP调试总卡壳?老工程师的3个断点盲区

