Мое приложение прослушивает сокет домена Unix (UDS) для входящих данных, в то время как nginx отправляет данные с помощью PHP. Отправка небольших фрагментов данных размером в несколько КБ работает отлично, но как только он достигает определенного предела, браузер получает ошибку 504 Gateway Time-out
, логи nginx
тайм-аут восходящего потока (110: тайм-аут соединения) при чтении ответа
заголовок из апстрима, клиент: 127.0.0.1, сервер: _, запрос: «GET
/foo/bar.php HTTP / 1.1 «, upstream:
«fastcgi: // unix: /run/php/php7.0-fpm.sock», хост: «localhost»
Сокет все еще получает некоторые данные (всегда размером около 1,5 МБ) и отвечает, но веб-сервер, похоже, не получает ответа.
Существуют ли ограничения потока 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 не имеет ничего общего с этим вопросом, это то, что PHP очень четко отправляет и получает данные.
Скорее всего, ваша удаленная система не закрывает сокет в нужное время или просто реагирует слишком долго.
while (($chunk = socket_read($this->socket, 2048, PHP_BINARY_READ)) !== FALSE)
{
$response .= $chunk;
if (substr($chunk, -1) == chr(27))
break;
}
Этот кодовый блок потенциально может быть бесконечным циклом с этим кодом, если удаленная система не закрыла соединение / сокет и сообщила вам о том, что будет продолжать пытаться читать и ждать 2048 (бит или байт — я никогда не могу вспомнить, какой size, который он запрашивает, чтобы убедиться, что комментарий проинформирует о данных, которые нужно пройти, или сокете, который будет закрыт до завершения чтения.
Таким образом, пара вещей, чтобы попытаться уменьшить количество прочитанных байтов, установит что-то вроде 128
вставьте таймер в сокет (требуется асинхронное программирование на PHP), так что убейте его через 28 секунд, дайте вашему коду еще 2 секунды для выполнения (безопасно выйдите). или использовать set_time_limit
увеличить ваш лимит времени.
Если вы увеличите лимит времени, вам нужно будет увеличить количество времени, которое nginx может получать от соединения с PHP, чтобы сделать это, fastcgi_read_timeout
В сообщении об ошибке указано, что время соединения между 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;
}