PHP服务报错500的排查过程

文章目录

        • 一、开启php服务报错日志
        • 二、php报错is_dir():open_basedir restriction in effect. File(.log) is not within the allowed path(s)
        • 三、php_network_getaddresses getaddrinfo failed redis 报错解决

架构是简单的单机 nginx + php , 没有并发量,收到500错误,一定是后端服务php的问题,500错误单从http协议的响应来看,是看不出什么错误的, 最好的方式是记录php错误日志。以下是 解决问题的思路,一步一步的来,

一、开启php服务报错日志
  • 1、查看nginx的日志

a) 首先找到nginx的配置文件,找到站点的日志文件;

b) access_log日志
access_log 日志一般配置在 server模块里面, 一个server 可以配置自己的 access_log , 但是这个access_log 一般只打印 nginx 从 fastcgi 进程收到的日志 和 客户端信息,格式也就是 什么浏览器, 从php-fpm返回的响应是 200 还是 500 或者其他状态码,咦!有500了,但是这里看不到500的详细错误,那就接着往下,找php的错误日志。

  • 2、php 的错误日志

php的错误日志包括 php-fpm 的错误日志 和 php.ini 的错误日志, 这两是不一样的,不要弄混。其中 php-fpm 的日志要优先级高一些,有的会覆盖php.ini 中的配置

a) php-fpm 的日志配置

如果是 php-fpm 的默认配置,那么他只会打印 php-fpm 的日志,不打印 php.ini 配置的 error_log 路径(即使配置,也不会打印), 这是因为 :

nginx只对页面的访问做access记录日志。不会有php的error log 信息。nginx把对php的请求发给php-fpm fastcgi进程来处理,默认的php-fpm只会输出php-fpm的错误信息,在php-fpm的errors log里也看不到php的errorlog。原因是php-fpm的配置文件php-fpm.conf中默认是关闭worker进程的错误输出,直接把他们重定向到/dev/null,所以我们在nginx的error log 和php-fpm的errorlog都看不到php的错误日志。

所以要想输出php的错误日志(看到详细的500错误),就需要改php-fpm配置(没有就新增)如下:

[global]
error_log = /www/server/php/72/var/log/php-fpm.log

[www]
catch_workers_output = yes 

注:catch_workers_output = yes:重定向运行过程中的 stdout 和 stderr 到主要的错误日志文件中。如果没有设置,stdout 和 stderr 将会根据 FastCGI 的规则被重定向到 /dev/null。默认值:无。

b) 配置php.ini 的错误日志

需要将php.ini中的配置指令做如下修改:

error_reporting = E_ALL;    将会向PHP报告发生的每个错误   
display_errors = Off;    不显示满足上条 指令所定义规则的所有错误报告   
log_errors = On;    开启错误日志   
log_errors_max_len = 1024;    设置每个日志项的最大长度   
error_log = /var/php_errors.log;    指定产生的 错误报告写入的日志文件位置

完成之后重新启动PHP服务生效。

systemctl restart php-fpm-72
二、php报错is_dir():open_basedir restriction in effect. File(.log) is not within the allowed path(s)

开启PHP错误日志后, /www/server/php/72/var/log/php-fpm.log 日志文件中出现了如下报错:

 WARNING: [pool www] child 8820 said into stderr: "NOTICE: PHP message: PHP Fatal error:  Uncaught thinkexceptionErrorException: is_dir(): open_basedir restriction in effect. File(/tmp/202401) is not within the allowed path(s): (/www/wwwroot/dock.lihan.ltd/runtime/:/www/wwwroot/dock.lihan.ltd/vendor/:/www/wwwroot/dock.lihan.ltd/config/:/www/wwwroot/dock.lihan.ltd/application:/www/wwwroot/dock.lihan.ltd/.env:/www/wwwroot/dock.lihan.ltd/public:/www/wwwroot/dock.lihan.ltd/thinkphp:/www/wwwroot/dock.lihan.ltd/vendor/composer:/www/wwwroot/dock.lihan.ltd/runtime:/www/wwwroot/dock.lihan.ltd/extend) in /www/wwwroot/dock.lihan.ltd/thinkphp/library/think/log/driver/File.php:61"

这种情况为open_basedir限制了PHP可以操作的文件目录,开发环境不考虑安全问题的话,如果需要操作这些文件,解决方法可以是:

在php.ini配置文件中设置open_basedir
例如:

open_basedir = "/www/wwwroot/project"

注:其实open_basedir 这个是用来限制php的目录访问权限什么的,如果不在允许的范围内,php就不能访问。

完成之后重新启动PHP服务生效。

systemctl restart php-fpm-72
三、php_network_getaddresses getaddrinfo failed redis 报错解决

当Redis无法解析Redis服务器的主机名时,会抛出错误“php_network_getaddresses getaddrinfo failed redis”。发生这种情况的原因有多种,例如 Redis 服务器 IP 地址或主机名配置不正确、网络连接问题或 DNS 解析问题。

  • 解决方案 - 以下是解决方法
    要修复错误“php_network_getaddresses getaddrinfo failed redis”,您可以实施以下解决方案:

  • 1.验证 Redis 服务器 IP 地址或主机名:确保 Redis 服务器配置文件中指定的 IP 地址或主机名正确。您还可以在 Redis 服务器上使用 ping 命令来检查客户端计算机的可达性。

  • 2.检查网络连接:验证客户端计算机和 Redis 服务器之间没有网络连接问题。使用 ping 命令检查是否有任何数据包丢失或网络延迟。

  • 3.检查 DNS 解析:如果您使用主机名连接到 Redis 服务器,请确保主机名可以解析为 IP 地址。在客户端计算机上使用 nslookup 命令检查主机名是否可以解析为 IP 地址。

  • 4.使用 IP 地址而不是主机名:如果 DNS 解析导致问题,请尝试使用 Redis 服务器的 IP 地址而不是 Redis 配置文件中的主机名。

通过实施这些解决方案,您应该能够从 PHP 应用程序建立到 Redis 服务器的连接,而不会遇到“php_network_getaddresses getaddrinfo failed redis”错误。

  • 注意
    当你在项目日志中遇到了下面的报错:
[ error ] [0]php_network_getaddresses: getaddrinfo failed: Name or service not known

首先可以检查php项目文件下面的隐藏文件:.env 文件

查看env文件中连接的所有服务,例如mysql、redis等,是否可连接,相信我,你会查到一些异常的。