如何调试“FastCGI sent in stderr: Primary script unknown while reading response header from upstream”并找到实
Posted
技术标签:
【中文标题】如何调试“FastCGI sent in stderr: Primary script unknown while reading response header from upstream”并找到实际的错误消息?【英文标题】:How to debug "FastCGI sent in stderr: Primary script unknown while reading response header from upstream" and find the actual error message? 【发布时间】:2016-05-17 15:50:10 【问题描述】:SO有很多文章提到这个错误代码:
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream...
这可能意味着此错误消息或多或少是无用的。
消息告诉我们,FastCGI 处理程序由于某种原因不喜欢它发送的任何内容。问题是有时我们不知道原因是什么。
所以我重新提出这个问题——我们如何调试这个错误代码?
假设我们有一个非常简单的站点,只有 phpinfo.php 文件。另外,还有一个非常简单的 nginx 配置,如下:
server
server_name testsite.local;
root /var/local/mysite/;
location /
index index.html index.htm index.php;
location ~ \.php$
include /etc/nginx/fastcgi_params;
fastcgi_pass fastcgi_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
我们如何才能看到输出/日志究竟是什么 fastcgi_params 被发送到脚本?
我们如何才能看到实际的错误信息? 就我而言,我使用的是 php-fpm。日志中没有关于此错误的信息。日志不会为此错误附加任何行。 php-fpm 有详细模式吗?
/var/log/php-fpm/error.log
/var/log/php-fpm/www-error.log
我已经尝试在 php-fpm.conf 文件中进行设置
log_level = notice
这在 php-fpm.d/www.conf 文件中:
catch_workers_output = yes
【问题讨论】:
【参考方案1】:回答您的问题:
-
在 php-fpm.d/www.conf 文件中:
设置 access.log 条目:
access.log = /var/log/$pool.access.log
重启php-fpm服务。
尝试访问您的页面
cat /var/log/www.access.log,你会看到如下访问日志:
- - 10/Nov/2016:19:02:11 +0000 "GET /app.php" 404
- - 10/Nov/2016:19:02:37 +0000 "GET /app.php" 404
解决“主脚本未知”问题:
如果您看到“GET /”没有正确的 php 文件名,那么这是您的 nginx 配置问题。
1234563 '无权访问你的文件,这让我困了 3 个小时)希望我的回答有帮助。
【讨论】:
我知道这是一个很老的答案,但这个答案对我来说比另一个答案更有意义。对我来说,第 2 点似乎是这样,但我没有任何用户“php-fpm”。我当前的用户有权访问该文件。不知道为什么它现在会发生。任何帮助将不胜感激。 如果你真的想看到 nginx 设置的主脚本,你应该在 www.conf 文件中启用access format
行。它比默认的更详细,包含%f
,这是真正的脚本文件。 ; %f: script filename ; Default: "%R - %u %t \"%m %r\" %s" access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %milid %kiloM %C%%"
别忘了重启你的php-fpm(例如systemctl restart php7.3-fpm
)
我间歇性地从 nginx 收到此错误消息。有时我会得到未知的主脚本和 404,有时我没有得到 200。无论哪种方式,我都会得到正确的脚本文件
在我的例子中,用户是 www-data 而不是 php-fpm【参考方案2】:
对我来说这是一个权限问题,我不得不更改 php-fpm/www.conf
中的用户和组
将值更改为您的用户名和组 _www,例如
user = aqib
group = _www
【讨论】:
【参考方案3】:Nginx 的 fastcgi_pass 不正确导致的问题。
您可以检查以下内容:
打开文件:/etc/php-fpm.conf
(systemctl status php-fpm
找到它)并在 = 之后找到 pid =
是您需要与您的路径进行比较的路径
listen =
在文件/etc/php-fpm.d/www.conf
2 路径必须到相同的位置。
例如:
pid = /run/php-fpm/php-fpm.pid
listen = /run/php-fpm/php-fpm.sock;
我的旧路径 listen = /var/run/php-fpm/php-fpm.sock;
和我更改为 /run/php-fpm/php-fpm.sock;
然后重新启动 php-fpm 然后它运行良好。
【讨论】:
【参考方案4】:由于请求是由 php worker 处理的,所以可以通过 php worker 追踪到原因。
为了方便定位哪个worker处理请求,在php-fpm的conf文件中只设置一个worker。
pm.max_children = 1
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1
使用$ps -aef | grep -v grep | grep php
获取php工作pid
root 28879 1 0 Apr12 ? 00:00:02 php-fpm: master process (/etc/php-fpm.conf)
www 28880 28879 0 Apr12 ? 00:00:24 php-fpm: pool www
然后用$ sudo strace -p 28880
跟踪工作过程,然后做请求,你会看到如下的跟踪输出
strace: Process 28880 attached
accept(10,
sa_family=AF_UNIX, [112->2]) = 4
poll([fd=4, events=POLLIN], 1, 5000) = 1 ([fd=4, revents=POLLIN])
times(tms_utime=1388, tms_stime=1099, tms_cutime=0, tms_cstime=0) = 1336709044
read(4, "\1\1\0\1\0\10\0\0", 8) = 8
read(4, "\0\1\0\0\0\0\0\0", 8) = 8
read(4, "\1\4\0\1\4U\3\0", 8) = 8
read(4, "\17DSCRIPT_FILENAME/data/HQ/SC_Edu"..., 1112) = 1112
read(4, "\1\4\0\1\0\0\0\0", 8) = 8
lstat("/data/www/public/st/mn/dst.php", 0x7ffce98d7170) = -1 ENOENT (No such file or directory)
stat("/data/www/public/st/mn", 0x7ffce98d9580) = -1 ENOENT (No such file or directory)
stat("/data/www/public/st", 0x7ffce98d9580) = -1 ENOENT (No such file or directory)
stat("/data/www/public", st_mode=S_IFDIR|0774, st_size=4096, ...) = 0
...
从跟踪输出中,它显示脚本文件/data/www/public/st/mn/dst.php
未退出
【讨论】:
【参考方案5】:在我的情况下,发生此错误是因为 php-fpm 无法根据$document_root
找到文件,即/etc/nginx/html
通过设置
location ~ \.php$
root /var/www/html;
fastcgi_index index.php;
...
PHP-FPM 现在可以正确定位文件了。
【讨论】:
【参考方案6】:检查root的位置以及它下面的文件是否存在,我遇到了这个错误,因为Root path TYPO。
【讨论】:
【参考方案7】:对我(Oracle Linux 7)来说,是 SELinux 阻止了 php-fpm 访问该文件。 Red Hat 和 Centos 用户可能会发现相同的情况。
运行
sestatus
显示 SELinux 的状态,对我来说它是打开导致问题。我已经尝试并实施了所有其他建议的修复,但错误仍然存在。
我通过将 SELinux 置于许可模式来解决它:
/etc/selinux/config
# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
我的最小配置的其余部分: /etc/nginx/nginx.conf:
user apache;
worker_processes 1;
events
http
include mime.types;
server
listen 80;
server_name 111.222.111.222; #your ip address
root /sites/demo;
index index.php index.html;
location ~ \.php$
# pass to php-fpm
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
注意:我将用户更改为apache,这是php-fpm使用的用户
/etc/php-fpm.d/www.conf:
The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /run/php-fpm/php-fpm.sock
; Set listen(2) backlog.
; Default Value: 511
;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = apache
listen.group = apache
listen.mode = 0660
注意:我将listen.owner 和listen.group 设置为apache
我的文件和文件夹的权限是: /站点(根:apache drwxrwxr-x) /sites/demo (root:apache drwxrwxr-x) /sites/demo/index.php (root:apache .rw.rw.r..)
如果您查看 ps -aux | grep -E "php|nginx" 可以看到所有的php-fpm pool进程和nginx worker进程都以用户apache运行。
如果您查看套接字文件 /run/php-fpm/php-fpm.sock 的权限,您将看到它由 apache:apache 和 srw-rw 拥有----
【讨论】:
【参考方案8】:对于MacOs用户,如果有人遇到我这种情况:
我已经启动了 php 服务:
sudo brew start php72
因为我使用了“sudo”权限是不同的。我需要在没有 sudo 的情况下停止和启动 php 服务。
sudo brew stop php72
brew start php72
希望对某人有所帮助。
【讨论】:
请在答案中更具体,因为此解决方案仅适用于 MAC OS 而不是 linux 糟糕.. 绝对正确!我刚刚添加了它。谢谢!以上是关于如何调试“FastCGI sent in stderr: Primary script unknown while reading response header from upstream”并找到实的主要内容,如果未能解决你的问题,请参考以下文章