调试着名的 - 在stderr中发送的FastCGI:"主脚本未知",同时从上游读取响应头

010*_*101 34 php nginx

SO有很多文章提到这个错误代码:

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream...
Run Code Online (Sandbox Code Playgroud)

这可能意味着此错误消息或多或少无用.

消息告诉我们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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们怎样才能看到输出/日志究竟是什么fastcgi_params被发送到脚本?

我们怎样才能看到实际的错误信息? 就我而言,我正在使用php-fpm.它在日志中没有关于此错误的信息.日志不会为此错误附加任何行.php-fpm有冗长的模式吗?

/var/log/php-fpm/error.log
/var/log/php-fpm/www-error.log
Run Code Online (Sandbox Code Playgroud)

我试过在php-fpm.conf文件中设置它

log_level = notice
Run Code Online (Sandbox Code Playgroud)

这在php-fpm.d/www.conf文件中:

catch_workers_output = yes
Run Code Online (Sandbox Code Playgroud)

小智 66

回答你的问题:

  1. 在php-fpm.d/www.conf文件中:

设置access.log条目:

access.log = /var/log/$pool.access.log
Run Code Online (Sandbox Code Playgroud)
  1. 重启php-fpm服务.

  2. 尝试访问您的页面

  3. 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

要解决"主要脚本未知"问题:

  • 如果你看到没有正确的php文件名的"GET /",那么这就是你的nginx conf问题.

  • 如果你看到404的"GET /app.php",这意味着nginx正确传递脚本文件名,但php-fpm无法访问此文件(用户"php-fpm:php-fpm"无法访问你的文件,困了我3个小时)

希望我的回答有所帮助

  • 我知道这确实是旧答案,但对我来说,这个答案比另一个答案更有意义。对我来说,第 2 点似乎是这种情况,但我没有任何用户“php-fpm”。我当前的用户有权访问该文件。即使现在也不知道为什么会发生。任何帮助,将不胜感激。 (2认同)
  • 如果您真的想查看 nginx 设置的主要脚本,您应该启用 www.conf 文件中的“访问格式”行。它比默认的更冗长,包含`%f`,这是真正的脚本文件。`; %f: 脚本文件名;默认值:"%R - %u %t \"%m %r\" %s" access.format = "%R - %u %t \"%m %r%Q%q\" %s %f % {mili}d %{kilo}M %C%%"` (2认同)

Kri*_*ofe 13

由于请求是由 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
Run Code Online (Sandbox Code Playgroud)

获取 php 工作 pid$ps -aef | grep -v grep | grep php

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
Run Code Online (Sandbox Code Playgroud)

然后使用 跟踪工作流程$ 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
...

Run Code Online (Sandbox Code Playgroud)

从跟踪输出来看,它显示脚本文件/data/www/public/st/mn/dst.php未退出