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

时间:2018-01-04 12:44:58

标签: php linux nginx unix-socket

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

  在读取响应时,

上游超时(110:连接超时)   来自上游的头,客户端:127.0.0.1,服务器:_,请求:“GET   /foo/bar.php HTTP / 1.1“,上游:   “fastcgi:// unix:/run/php/php7.0-fpm.sock”,主持人:“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;
    }
}

2 个答案:

答案 0 :(得分:1)

对于州政府来说,Nginx与这个问题毫无关系,这是非常明显的PHP发送和接收数据。

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

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

如果远程系统没有关闭连接/套接字并且告诉你它将继续尝试读取并等待2048(Bit或Bytes - 我可以),此代码块有可能是这个代码的无限循环在读取完成之前,永远不要记得它要求确定评论通知的数据的大小或要关闭的套接字。

因此,尝试降低读取字节的一些事情将其设置为128,将套接字放入套接字(需要在PHP中进行异步编程)读取,以便在28秒后将其删除给出代码再执行2秒(安全退出)。或使用set_time_limit来增加时间限制。

如果您确实增加了时间限制,则需要增加允许nginx从PHP连接获取响应的时间来设置fastcgi_read_timeout

答案 1 :(得分:0)

The error states that connection timed out between Nginx and upstream server.

Does your request take more then 1 minute to complete?

Try to change the nginx location as per follow and read about 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;
}