nginx 将数据不完整地传输到 unix 域套接字

ngnix transfers data to a unix domain socket incompletely

我的应用程序正在 unix 域套接字 (UDS) 上侦听传入数据,而 nginx 正在使用 PHP 发送数据。发送几个 KB 的较小数据块工作完美,但一旦达到一定限制,浏览器就会收到错误 504 Gateway Time-out,nginx 日志

upstream timed out (110: Connection timed out) while reading response header from upstream, client: 127.0.0.1, server: _, request: "GET /foo/bar.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock", host: "localhost"

套接字仍会获取一些数据(总是减少大约 1.5 MB)并回复,但网络服务器似乎没有收到回复。 是否有任何必须调整的 UDS 流限制或 nginx 变量?

PHP代码:

public function send ($msg)
{
    $str = "{$msg}".chr(27);

    $ret = socket_write($this->socket, $str, strlen($str));

    if ($ret == FALSE)
    {
        return false;
    }
    else
    {
        $response = "";

        while (($chunk = socket_read($this->socket, 2048, PHP_BINARY_READ)) !== FALSE)
        {
            $response .= $chunk;

            if (substr($chunk, -1) == chr(27))
                break;
        }

        //close the connection
        if ($this->connected !== false)
        {
            socket_shutdown($this->socket);
            socket_close($this->socket);
            $this->connected = false;
        }

        return $response;
    }
}

错误指出 Nginx 和上游服务器之间的连接超时。

您的请求是否需要超过 1 分钟才能完成?

尝试按照以下内容更改 nginx 位置并阅读有关 fastcgi_read_timeout

location ~* \.php$ {
    include         fastcgi_params;
    fastcgi_index   index.php;
    fastcgi_read_timeout 120;
    fastcgi_pass    127.0.0.1:9000;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
}

好的,对于陈述者来说,Nginx 与这个问题无关,很明显 PHP 发送和接收数据。

很可能您的远程系统没有在正确的时间关闭套接字,或者只是需要很长时间才能响应。

while (($chunk = socket_read($this->socket, 2048, PHP_BINARY_READ)) !== FALSE)
{
    $response .= $chunk;
    if (substr($chunk, -1) == chr(27))
    break;
}

如果远程系统没有关闭 connection/socket 并告诉您它将继续尝试读取并等待 2048(位或字节 - 我永远不记得它要求的大小,以确保注释会通知)在读取完成之前要通过的数据或要关闭的套接字。

所以有几件事可以尝试降低你的读取字节,将它设置为类似 128 的东西,在你的套接字中放置一个计时器(需要在 PHP 中进行异步编程)读取所以杀死它28 秒后,再给你的代码 2 秒来执行(安全退出)。或使用 set_time_limit 增加您的时间限制。

如果你确实增加了你的时间限制,你将需要增加允许 nginx 从连接到 PHP 的响应的时间量来做到这一点设置你的 fastcgi_read_timeout