NGINX: тайм-аут восходящего потока (110: тайм-аут соединения) при чтении заголовка ответа из восходящего потока

130

У меня Puma работает как восходящий сервер приложений, а Riak - как мой фоновый кластер БД. Когда я отправляю запрос, который сокращает фрагмент данных примерно для 25 тысяч пользователей и возвращает его из Riak в приложение, я получаю сообщение об ошибке в журнале Nginx:

Истекло время ожидания восходящего потока (110: Истекло время ожидания соединения) при чтении заголовка ответа из восходящего потока

Если я запрашиваю свой апстрим напрямую, без прокси-сервера nginx, с тем же запросом я получаю необходимые данные.

Тайм-аут Nginx наступает после установки прокси.

**nginx.conf**

http {
    keepalive_timeout 10m;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    include /etc/nginx/sites-enabled/*.conf;
}

**virtual host conf**

upstream ss_api {
  server 127.0.0.1:3000 max_fails=0  fail_timeout=600;
}

server {
  listen 81;
  server_name xxxxx.com; # change to match your URL

  location / {
    # match the name of upstream directive which is defined above
    proxy_pass http://ss_api; 
    proxy_set_header  Host $http_host;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache cloud;
    proxy_cache_valid  200 302  60m;
    proxy_cache_valid  404      1m;
    proxy_cache_bypass $http_authorization;
    proxy_cache_bypass http://ss_api/account/;
    add_header X-Cache-Status $upstream_cache_status;
  }
}

В Nginx есть несколько директив тайм-аута. Не знаю, упускаю ли я что-то важное. Любая помощь будет высоко ценится....

user2768537
источник
Он должен тайм-аут только после 600 секунд? Вы можете подделать время, настроив tcp-сервер на 127.0.0.1:3000, который просто принимает соединения и ничего не делает с ними, чтобы посмотреть, сколько времени это займет. Должно быть 600s ...
rogerdpack

Ответы:

47

Это происходит потому, что вашему восходящему потоку требуется слишком много времени, чтобы ответить на запрос, и NGINX считает, что восходящий поток уже не смог обработать запрос, поэтому он отвечает с ошибкой. Просто включите и увеличьте proxy_read_timeout в locationблоке конфигурации. То же самое произошло со мной, и я использовал тайм-аут в 1 час для внутреннего приложения на работе:

proxy_read_timeout 3600;

При этом NGINX будет ждать час (3600 с), пока его восходящий поток что-то не вернет.

Серхио Гонсалес
источник
6
Обратите внимание, что наличие proxy_read_timeoutв разделе http может не помочь. У меня есть proxy_passдиректива в разделе местоположения, и только там proxy_read_timeoutнастройка имеет значение. (nginx 1.16.0)
JonnyJD
Кажется, у меня работает http / server / location ... может быть, все изменилось :)
rogerdpack
39

Вы всегда должны воздерживаться от увеличения тайм-аутов, я сомневаюсь, что время ответа вашего внутреннего сервера является проблемой в любом случае.

Я обошел эту проблему, сняв флаг активности соединения и указав версию http в соответствии с ответом здесь: https://stackoverflow.com/a/36589120/479632

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

        # these two lines here
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_pass http://localhost:5000;
    }
}

К сожалению, я не могу объяснить, почему это работает, и мне не удалось расшифровать это из документов, упомянутых в ответе, поэтому, если у кого-то есть объяснение, мне было бы очень интересно его услышать.

Almund
источник
1
Почему бы вам не настроить, proxy_read_timeoutесли вы знаете, что прокси (даже для определенного URL-адреса) требует больше времени на обработку?
Джош М.
Здравствуй! Я больше не помню точную проблему, но я думаю, что это не было связано с фактическим временем для URL-адреса, а скорее с тем, что тайм-аут не обрабатывался правильно без этих настроек.
Almund
@magicbacon, это было много лет назад, так что я почти не помню этот случай, но вы изменили $http_hostправо? Я предполагаю, что это не сработает для https. Возможно, потребуются дополнительные настройки для проксирования https-запросов.
Альмунд
+1 ... это похоже на неудобный взлом, но на самом деле это из официальных документов :) nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive У меня немного другая проблема "соединение с восходящим потоком преждевременно закрыто при чтении ответа заголовок из восходящего потока ", когда я использую директиву восходящего потока с keepalive, и использование этих двух строк, кажется, исправляет это.
Karussell
1
@TimDavis Понятно, может так и лучше. Я предполагаю, что это может зависеть от трафика, как в этом посте, где говорится, что это требуется для WebSockets: serverlab.ca/tutorials/linux/web-servers-linux/…
Альмунд,
26

Сначала выясните, какой восходящий поток замедляется, проконсультировавшись с файлом журнала ошибок nginx и соответствующим образом отрегулируйте время чтения, в моем случае это был fastCGI

2017/09/27 13:34:03 [error] 16559#16559: *14381 upstream timed out (110: Connection timed out) while reading response header from upstream, client:xxxxxxxxxxxxxxxxxxxxxxxxx", upstream: "fastcgi://unix:/var/run/php/php5.6-fpm.sock", host: "xxxxxxxxxxxxxxx", referrer: "xxxxxxxxxxxxxxxxxxxx"

Поэтому мне нужно настроить fastcgi_read_timeout в конфигурации моего сервера

 location ~ \.php$ {
     fastcgi_read_timeout 240;
     ...
 }

См .: исходный пост

Руберандинда терпение
источник
Вот способ добавить информацию о времени, когда невозможно увидеть, сколько вам «нужно», чтобы увеличить его: stackoverflow.com/questions/18627469/… FWIW
rogerdpack
10

В вашем случае это поможет небольшая оптимизация прокси, или вы можете использовать "# настройки тайм-аута"

location / 
{        

  # time out settings
  proxy_connect_timeout 159s;
  proxy_send_timeout   600;
  proxy_read_timeout   600;
  proxy_buffer_size    64k;
  proxy_buffers     16 32k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;
  proxy_pass_header Set-Cookie;
  proxy_redirect     off;
  proxy_hide_header  Vary;
  proxy_set_header   Accept-Encoding '';
  proxy_ignore_headers Cache-Control Expires;
  proxy_set_header   Referer $http_referer;
  proxy_set_header   Host   $host;
  proxy_set_header   Cookie $http_cookie;
  proxy_set_header   X-Real-IP  $remote_addr;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Server $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Димитриос
источник
Для меня имеет значение наличие этих настроек в разделе местоположения . Их наличие в разделе http не помогло (возможно, потому, что у меня также было их proxy_passв разделе местоположения .
JonnyJD
Что именно вы оптимизируете с помощью этих объявлений?
Влад
9

Я думаю, что эта ошибка может возникать по разным причинам, но может быть специфичной для используемого вами модуля. Например, я видел это с помощью модуля uwsgi, поэтому пришлось установить uwsgi_read_timeout.

Ричард
источник
2
Думаю, uwsgi_read_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; работает для меня.
тян
9

Я бы рекомендовал взглянуть на error_logs, в частности, на восходящую часть, где он показывает конкретный восходящий поток, который истекает.

Затем в зависимости от этого вы можете настроить proxy_read_timeout, fastcgi_read_timeoutили uwsgi_read_timeout.

Также убедитесь, что ваш конфиг загружен.

Подробнее здесь Истекло время ожидания восходящего потока Nginx (почему и как исправить)

gansbrest
источник
4

Как указывали здесь многие другие, увеличение настроек тайм-аута для NGINX может решить вашу проблему.

Однако увеличение настроек тайм-аута может быть не таким простым делом, как предлагают многие из этих ответов. Я сам столкнулся с этой проблемой и попытался изменить настройки тайм-аута в файле /etc/nginx/nginx.conf , как предлагают почти все в этих потоках. Это мне нисколько не помогло; в настройках тайм-аута NGINX не было явных изменений. Теперь, много часов спустя, мне наконец удалось решить эту проблему.

Решение находится в этой ветке форума , и в нем говорится, что вы должны поместить настройки тайм-аута в /etc/nginx/conf.d/timeout.conf (и если этот файл не существует, вы должны его создать). Я использовал те же настройки, что и в ветке:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
Андреас Форслёв
источник
1

У меня была та же проблема, и в результате в контроллере рельсов возникала ошибка «каждый день». Я не знаю почему, но на производстве puma снова и снова запускает ошибку, вызывая сообщение:

Истекло время ожидания восходящего потока (110: Истекло время ожидания соединения) при чтении заголовка ответа из восходящего потока

Вероятно, потому что Nginx снова и снова пытается получить данные от puma. Забавно то, что ошибка вызвала сообщение о тайм-ауте, даже если я вызываю другое действие в контроллере, поэтому одна опечатка блокирует все приложение.

Проверьте свой файл log / puma.stderr.log, чтобы узнать, так ли это.

aarkerio
источник
0

С нашей стороны использовался spdy с кешем прокси. Когда срок действия кеша истекает, мы получаем эту ошибку до тех пор, пока кеш не будет обновлен.

timhaak
источник
0

Надеюсь, это кому-то поможет: я столкнулся с этой ошибкой, и причиной было неправильное разрешение в папке журнала для phpfpm, после изменения ее, чтобы phpfpm мог писать в нее, все было в порядке.

Маурисио Отта
источник
0

Для proxy_upstreamтайм-аута я попробовал вышеуказанные настройки, но они не сработали.

Настройка resolver_timeoutсработала для меня, зная, что на создание сообщения о тайм-ауте восходящего потока уходит 30 секунд. Например, me.atwibble.com не может быть решен (110: время ожидания истекло) .

http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver_timeout

Дэвид Мерсер
источник