当前位置: 首页 > 科技观察

502错误,让你进一步了解Nginx和PHP-FPM的关系

时间:2023-03-13 15:11:12 科技观察

今天回顾一下当时遇到的一个502问题以及最佳解决方案。不要小看这个502错误,充分的了解是非常有必要的,希望大家可以通过本文学到一些知识。在我的例子中,Nginx通过FastCGI协议连接到PHP-FPM(7.1)。Nginx和PHP-FPM部署在同一台机器上。配置完成后,浏览器访问报502错误。首先引用百科上对502的介绍:服务器作为网关或代理,收到上游服务器的无效响应。这意味着Nginx没有得到PHP-FPM的响应。我当时着急处理,弄了半天。这里忽略各种排查过程,先贴出正确的配置(与此问题相关)。(1)nginx.conf:error_loglogs/error.log;用户www-数据www-数据;(2)php-fpm.conf:access.log=/var/log/fpm.log(3)pool.d/www.conf(PHP-FPM池配置文件):user=www-datagroup=www-datalisten=/run/php/php7.1-fpm.socklisten.owner=www-data(出错时的配置:listen.owner=www)listen.group=www-data(出错时的配置:listen.owner=www)listen.mode=0660access.log=/var/log/fpm-www.access.log然后解释pool配置文件,一般情况下,一个nginx的虚拟主机对应一个php-fpmpool文件,这样不同的php-fpm工作进程相互隔离,互不影响。接下来介绍解决过程:1:出现502问题时,观察nginx的error.log文件,会报如下错误:2018/09/1818:34:32[crit]2831#0:*493connect()tounix:/run/php/php7.1-fpm.sockfailed(13:Permissiondenied)whileconnectingtoupstream,client:18.179.21.152,server:www.simplehttps.com,request:"GET/1.phpHTTP/1.1",upstream:"fastcgi://unix:/run/php/php7.1-fpm.sock:",host:"www.simplehttps.com"其实我说的很清楚了。连接PHP-FPM时遇到权限问题。2:观察php主进程的error.log,发现/var/log/fpm.log文件没有任何输出。查阅了官方资料,对error_log命令的解释非常少。我猜有两个影响:每个池的错误将被重定向到这个文件。(经测试,池错误与本文件无关)PHP-FPM主进程的一些控制错误。(从这个案例来看,主进程并不知道Nginx遇到了错误,所以没有错误输出)***,php-fpm.conf下的error_log命令在我看来没有任何实际用处,如果读者知道的,欢迎指导。(3)定位问题得知nginx通过本地socket连接php-fpm遇到权限问题,定位listen.owner和listen.group命令。问题的原因是nginx进程的属主和php-fpm的属主权限不一样。出现502问题时,nginx的owner是www-data,listen.owner是www。修改成一致后,问题解决。我们不禁要问,listen.owner和listen.group指令是什么意思?看官方介绍:;为unixsocket设置权限,如果一个被使用。在Linux中,读/写;这时socket的权限必须和web服务器的操作(读)权限一致。读者大概明白这是什么意思。user和group这两个命令是什么意思?为什么它们与listen.owner命令如此相似?官方介绍是这样的:;Unixuser/groupofprocesses不是很清楚,但其实显示了这个php-fpm进程本身的权限(可以通过psaux|grepphp-fpm进一步确认),如果php-fpm要向nginx传递了错误的数据,那么user和group指令必须和nginx的用户指令配置一样(后面会写文章说明)。这也间接说明,如果nginx的user命令与php-fpm工作进程的listen.user命令配置不同,则不会影响两者的交互。只是在本机中,如果nginx和php-fpm要读取或操作同一个文件,需要进行同样的配置。我希望每个人都能仔细理解这一点。其实最简单的方案就是通过tcp连接nginx和php-fpm(即www.conf配置listen=127.0.0.1:9000),这样就不会有权限操作的问题,但是对于本机来说,socket连接的速度比tcp连接更有保障。