服务器PHP页面加载慢/报错 排查思路与解决方法

amuwap 发布于 3 小时前 2 次阅读


半夜三点的时候,收到了老板发过来的微信,其询问网站是不是出现挂掉的情况了。你当时睡眼还很惺忪地打开了电脑,而后按下了F12,结果看到满屏都是500错误。这般场面在PHP开发之中是极为常见的,不过每当遇到之时,依旧还是会让人心头头皮发麻。不要慌张,因为页面加载出现错误可不单单只是你所面临的类似很可怕的情况,而是关乎于所有PHP开发者的日常状况,关键之处在于是不是拥有一套顺手而且好用的排查流程。

开发者工具是第一现场

按下F12并非做做样子,而是去查看请求的实际状态,着重留意呈现红色状态的请求,显示404意味着文件已不存在,500表示服务器内部出现错误,403表明权限受到阻拦。在Network面板当中能够看见究竟是哪个接口出现超时情况、哪个资源在加载到一半时中断,甚至就连请求所耗费的时间都标记得十分清晰明了。像是昨天就有一位客户称后台登录页面呈现白屏现象,一经检查发现是某个CSS文件返回了503,追根溯源是CDN欠费所致,不要凭借猜测,要依据数据来阐明情况。

Console面板同样不可被忽视,好多情形 JavaScript报错通常会直接致使页面渲染出现卡顿现象,你误以为PHP已然出现故障,实际上是前端代码未能正常运行,跨域方面的问题、未被定义的变量、语法方面的差错,Console当中都会直接给出提示,存在这样一个小窍门,右键点击Network列表,勾选“保留日志”选项,刷新页面之时也不会将记录清空,这对于排查跳转类错误而言极为有效。

PHP错误日志是藏宝图

不要对着浏览器呈现的白屏处于发呆状态而去那服务器上面去翻动日志,PHP的错误日志默认情况下有可能并未开启,又或者是不清楚存放的位置所在之处。你能够在项目入口文件那儿临时添加两行代码:ini_set(‘display_errors’, 1); ini_set(‘log_errors’, 1);,以此强制让错误得以显示出来。然而正式环境千万不要这么去做,这样会将路径以及数据库信息暴露出来,是极为危险的。

办法正确的是寻得php.ini之中的error_log这一项目,去瞧日志究竟写到了哪一个文件。好多云主机依照默认状况把PHP错误抛入系统日志,跟一众毫无关联的信息掺和在了一块儿。能够借助tail -f实时地注视着日志的输出,刷新页面,错误瞬间呈现。前面几天帮一位同行查看问题,他笃定说是服务器配置出现了差错,然而日志里记载着“内存大小已然耗尽”,明显是在循环之中让数组越读越大了。

运行环境配置常在暗处伤人

环境配置经过变动然而并未进行服务重启,如此一来这便成了最为隐匿的错误根源,关于 nginx 修改完毕须得重载,php - fpm 修改完成要有重启操作好些人遗漏这一环节。另外存在一个常见的陷阱,open_basedir 对 php 可访问的目录予以限制,要是项目运用了临时目录或者外部存储,当不在允许列表之中时便会径直反馈权限错误在浏览器所呈现的便是一片空白。

当上载功能发生问题之际,别急于去修改代码,首先要去翻看php.ini里的upload_max_filesize以及post_max_size。用户上传一张8M的图片却遭遇失败,然而服务器所设置的限制仅仅才2M。另外还有一个较为冷门的参数max_input_vars,要是表单字段格外多,比方说后台权限配置一次性提交几百个复选框,一旦超出限制便会直接导致后台无法进入。这些配置项改完记得重启,不然白忙活。

扩展和组件并非总是就绪

接手那种老项目的时候,最怕碰到这样的情况,在本地运行得很正常,可是一旦上传到服务器,就会报“类不存在”,大概是少安装了扩展来着。在Linux上面安装PHP扩展得去敲命令,而在Windows系统下,还得手动把php.ini里的注释给删掉才行。就像php_curl这种、php_mysqli此种、php_gd2这般,这些全都是高频依赖。要是忘了安装gd库,验证码就显示不出来,用户还会误以为网站被黑了呢。

并且存在版本兼容方面的问题,PHP 8将许多PHP 7时期的废弃函数给删除了,像mysql_connect这样早就不应该再使用的函数,然而有些旧代码却仍然在使用,在升级之前最好借助兼容性检查工具进行一次扫描,之前有一位客户对PHP版本进行升级,结果订单打印功能完全崩溃,经过一下午的查找发现是使用了PHP 7.4才废弃的each()函数,将其改掉后立刻恢复正常。

缓存和数据库是沉默的杀手

缓存文件无法写入时不会报错,而是只会致使页面无变化。需检查缓存目录是否具备写入权限,特别是在Linux系统下若用户组别弄错的情况。Nginx运行用户是网站数据存储网页缓存使用的用户,目录属主若为另一个用户,那么写入缓存必定失败。另外还有一个容易出错的地方:使用了Redis或Memcached,然而服务未启动,PHP连不上时不会报致命错误,只是读取不到数据,页面会显得缓慢或者呈空白状态、页面出现空白的情况。

数据库连接的超时情况是颇为隐蔽的。其中,MySQL的wait_timeout,在默认状态下是8小时。要是程序采用的是长连接,那么第二天早上第一波用户常常遭遇到连接已然断开的状况。对于该情况,错误日志里并不会给出明显的提示。其往往呈现为“页面加载极度缓慢”或者“部分数据无法展示出来”这样的情形。有一种解决办法,那就是在业务处于低峰期的时候,手动去重启PHP - FPM,以此来清空持久连接。或者,也能够在框架层面配置自动重连的机制。

调试工具是最后的透视镜

翻遍了日志,查遍了配置,依旧毫无头绪,那就得动用调试工具了。Xdebug是PHP开发者的瑞士军刀,安装好之后,在IDE里设置断点,逐行查看变量如何变化。有时逻辑出现偏差,是因为某个if判断始终为假,肉眼难以察觉,一步步跟踪下去,就会发现是===对两个不同类型的值进行了比较。

如果不使用Xdebug,那么较为硬核的开发者会在代码之中书写file_put_contents来自行进行日志记录,尽管其较为原始但却具备效能。尤其是在生产环境下不适宜安装扩展时,便会于关键节点处将变量值写入至本地文件当中。要记得添加微秒时间戳,以此便于按照顺序去还原执行流程。有一位同事借助此方法排查出了一个颇为诡异的bug:某一台服务器的时区设置出现错误,进而致使时间判断逻辑全然偏离正轨。

你近来碰到的PHP页面加载出现的错误,最为耗费时间的究竟是哪一类别——是代码自身所存在的问题,又或者是环境配置方面挖下的坑?在评论区将其分享出来,以此帮助其他的人减少走弯路的情况,要是有用的话记得去点赞并且转发。