Linux下PHP开发环境搭建实战指南
|
上线前发现那个致命问题的那一刻,我就知道不是环境问题——是环境太干净了。去年6月份,运维那边把PHP 8.1打了个包扔过来,说“开箱即用”,结果我们测试机上跑冒烟用例崩得比新来的实习生还快。我原以为是docker-compose.yml里某个卷挂载错了,结果盯了两小时日志,发现连error_reporting都没打开,E_NOTICE直接吃掉,var_dump()输出卡在buffer里不出来。谁桌上摆着三台手机,中间那台还在连着WiFi测弱网重传——这会儿它突然震了一下,我手一抖关掉了终端。 键盘上有个键按下去不回弹。Ctrl+C都得按两下才生效,气得我把xterm最小化了三次。张工蹲在机柜前面拔网线,说“试试宿主机直连”,王婷在白板上写PHP-FPM的pm.max_children,数字擦了一半,底下露着前天遗留的SQL优化建议。外卖凉透了——葱油拌面,汤全凝成冻,我拿筷子戳了三下才挑出面条。 “优胜劣汰”这词真不是吹的。不是说你搭得对不对,是你搭完以后,什么玩意儿能活下来。比如那个curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false)硬编码进公共配置的写法,本地、测试、预发全过,就线上502——因为云WAF偷偷加了OCSP stapling校验。开发说“没改过PHP配置啊”,可php.ini里disable_functions漏掉了proc_open,CI/CD流水线里那个check_php_extension.sh脚本早就不跑了,三年前谁写的?记不清是哪个迭代了,反正提单的时候写的是“阻塞级”,后来降成P2,最后归档状态是“非必现,暂不修复”。 会议室又被占了,投影仪还亮着,PPT停在“微服务拆分路径图”第7页,右下角时间戳是上午10:43。我站在门口念叨:php-fpm -t报错,但提示居然是“configuration file /etc/php/8.1/fpm/php.ini test failed”,而实际出问题的是pool.d/www.conf里listen.mode写成了0666——八进制,但fpm-master根本没权限创建socket文件。这毛病,本地Docker里压根不会触发,因为root跑的。生产环境uid/gid一卡住,worker全挂。漏测的案例就这一个:没覆盖到非root用户启动fpm的路径。主观判断是——只要没在非特权用户上下文里跑过一次完整回归,这环境就算没搭完。 用例管理工具一直在转圈。转了四分十七秒,进度条卡在92%。我没等它,切回去看jenkins构建记录,发现build #3412里有一行log被截断了:“Warning: mysqli::real_connect(): (HY000/2002): Connection refused in /var/www/html/lib/db.php on line 47”。后面跟着一个空行,再后面是“[Pipeline] sh”。这错误在测试机里从没出现过——因为我们的MySQL是容器链路,host写的是db,而线上是域名,DNS解析走的是阿里云内网,TTL配的是300,刚好卡在服务重启的间隙里。边界?哪有什么边界,全是灰度缝里钻出来的线头。 李工昨天说,“你们测环境跟生产差半步,就等于差十万八千里”。我说对,但他马上补一句:“所以我们要用Ansible统一编排”。结果他提交的playbook里,template模块漏写了backup: yes,覆盖了旧php.ini,连date.timezone都回不去了。这事儿我没追——反正复现不了,提单也打不通。偶现的bug你没法打标签,优先级填什么都心虚。我盯着那行“Connection refused”,突然想起上周五下午三点,测试机硬盘报警红灯亮了11分钟,后来静音了,没人去换。那块盘是放临时测试数据的,上面还跑着memcached,key过期策略是默认0,缓存永远不淘汰。现在想想,有些500不是PHP的事,是/dev/sdb1读慢导致fpm worker卡死超时……但谁查这个? 白板上的数字擦了一半,剩下“3827”和半个“9”,像被谁用指甲抠过。我掏出手机搜“php 8.1 fpm socket permissions”,点开第三个链接,是Stack Overflow上2021年的回答,答主说“chmod 660 /run/php/php8.1-fpm.sock && chown www-data:www-data …”,我截图发到群里,张工回了个“✓”,十分钟后他发来另一张图:ls -l /run/php/,socket文件属主是root:root。我懒得解释了。用例覆盖率这事吧,我们组去年平均67%,但PHP这块只跑了51%——缺的是cli模式下pcntl_fork异常分支,因为用例库里写着“该场景依赖系统信号量,暂不模拟”。暂时不模拟的东西,最后都变成线上事故里的“没想到”。
文章配图,仅供参考 测试机的充电线不够长,我拽着它挪位置,插头差点从排插里崩出来。这事跟PHP环境无关,但它让我想起,我们连物理层面的供电冗余都没测过——服务器断电再上电,fpm master pid文件残留,worker起不来,而supervisor又误判为正常。这种事,你指望谁写用例?我自己那份没人看的用例,写了二十一条启动失败场景,其中十七条带条件判断:“若/etc/default/php8.1-fpm中RUNLEVEL不为‘S’则跳过”,结果没人review,也没人执行。它就躺在jira里,状态是“已编写”,更新时间是去年4月。我原以为装完extension就能收工,结果oci8扩展依赖instantclient 21.11,但yum源里只有19.8,手动装完又报libaio.so.1找不到——原来测试机没装libaio-utils。这种依赖链断裂,不是文档没写清楚,是文档根本不提“依赖链”这三个字。环境搭建指南最大的幻觉,就是以为人能靠读文档搭出真实世界。真实世界里,是PHP进程在跑,不是文档在跑。 先扔结论后补细节。Linux下PHP开发环境搭建,本质上是一场剔除幻觉的手术。刀尖所指,不是配置项对错,而是你敢不敢让worker用nobody用户跑满24小时,敢不敢关掉SELinux再试一次,敢不敢在/tmp里塞满小文件然后启动fpm。其他都是浮沫。 下周我想把所有测试机的umask统一改成0002,然后再拉张工一起跑一遍全路径权限审计——至少先看看那些.sock文件是谁造的,又是谁删的。至于php.ini里那一千行注释?先留着。删太快,怕漏掉最后一行真正有用的。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


Linux服务器从零搭建到稳定运行全实战
20年架构师亲授:30分钟搞定Linux生产环境搭建
鸿蒙开发环境Unix调试失败?90%卡在这3个隐蔽配置
Linux环境搭建太慢?3步避坑提速
PHP服务器安全审计:90%高危漏洞藏于配置末行
Linux与Windows服务器选型的5大性能陷阱
Linux深度学习环境搭建:从报错到运行的完整排障实战
