Зворотний проксі Nginx, що спричиняє 504 тайм-аут шлюзу


129

Я використовую Nginx як зворотний проксі, який приймає запити, то робить proxy_pass, щоб отримати фактичний веб-додаток від верхнього сервера, що працює на порту 8001.

Якщо я заходжу на mywebsite.com або роблю wget, я отримую 504 тайм-аут шлюзу через 60 секунд ... Однак, якщо я завантажую mywebsite.com:8001, програма завантажується як очікувалося!

Тож щось заважає Nginx спілкуватися з сервером висхідного потоку.

Все це почалося після того, як моя хостингова компанія скинула машину, на якій працювали мої речі, до цього жодних питань не було.

Ось мій блок сервера vhosts:

server {
    listen   80;
    server_name mywebsite.com;

    root /home/user/public_html/mywebsite.com/public;

    access_log /home/user/public_html/mywebsite.com/log/access.log upstreamlog;
    error_log /home/user/public_html/mywebsite.com/log/error.log;

    location / {
        proxy_pass http://xxx.xxx.xxx.xxx:8001;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
} 

І вихід з мого журналу помилок Nginx:

2014/06/27 13:10:58 [error] 31406#0: *1 upstream timed out (110: Connection timed out) while connecting to upstream, client: xxx.xx.xxx.xxx, server: mywebsite.com, request: "GET / HTTP/1.1", upstream: "http://xxx.xxx.xxx.xxx:8001/", host: "mywebsite.com"

Чи працює сервер SELinux?
CrackerJack9

У моєму випадку, шлюз NAT був проблемою, а не NGINX або резервним API. stackoverflow.com/a/62351959/9956279
Sushilinux

Відповіді:


152

Можливо, ви можете додати ще кілька рядків, щоб збільшити період очікування вгору за течією. Наведені нижче приклади встановлюють час очікування на 300 секунд:

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;

5
Я думаю, що збільшення часу очікування рідко є відповіддю, якщо ви не знаєте, що ваша мережа / служба завжди або в деяких випадках реагуватимуть дуже повільно. Зараз небагато веб-запитів може зайняти більше декількох секунд, якщо ви не завантажуєте контент (файли / зображення)
Альмунд,

@Almund Я думав те саме (майже не намагався це пробувати), але з будь-якої причини це просто працювало для мене. (Раніше вичерпано через 60 секунд, зараз отримайте відповідь негайно).
Дакс Фол

@Dax Fohl: Це цікаво. Я зняв джерело і швидко продивився, і з того, що я бачу, встановлення будь-якого параметра proxy_ убік від proxy_pass ініціалізує купу налаштувань, які, я вважаю, буде запускати проксі по-іншому, тому, можливо, все, що дасть, дасть це те саме поведінка.
Альмунд

Не вирішив проблему для мене, використовуючи її з сервером
nodejs

3
Я вважаю, що мені потрібен лише тег proxy_read_timeoutпри налагодженні в бекенді. Дякую!
Джефф Пукетт

79

Збільшення тайм-аута, ймовірно, не вирішить вашу проблему, оскільки, як ви кажете, фактичний цільовий веб-сервер реагує просто чудово.

У мене був цей самий випуск, і я виявив, що це пов'язано з тим, що не використовую живого зв'язку під час з'єднання. Насправді я не можу відповісти, чому це так, але, очистивши заголовок з'єднання, я вирішив цю проблему, і запит був проксі проксі:

server {
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://localhost:5000;
    }
}

Перегляньте це повідомлення, яке пояснює це більш докладно: nginx закрити підключення до потоку після запиту Роз'яснення в заголовку в режимі "живі" http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive


7
МЕСЯЦІ проблем, що вирішуються одним рядком proxy_set_header Connection "";, хай, не використовуйте runcloud
киває

22

user2540984 , а також багато інших вказали, що ви можете спробувати збільшити налаштування тайм-ауту. Я сам стикався з подібною проблемою з цим і намагався змінити налаштування тайм-ауту у файлі /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;

Це може бути не вирішенням вашої конкретної проблеми, але якщо хтось інший помітить, що час / час зміни в /etc/nginx/nginx.conf нічого не робить, я сподіваюся, що ця відповідь допоможе!


привіт, в моєму каталогу config.d немає timeout.conf. Ви сказали, що створіть його, і я хочу його підтвердити, просто додайте вищевказані налаштування в timeout.conf?
tktktk0711

Так, просто додайте їх. Ви можете змінювати їх для власних потреб, але вони працювали для мене!
Andreas Forslöw

На жаль, у садибі Laravel з ubuntu та Nginx це не працює. :( Ви маєте на увазі просто додати ці рядки? Без server{}або щось інше? Ця помилка з’являється відразу через 5 хвилин. Я перезавантажую, перезавантажую, і це ніколи не проходить через ці 5 хвилин або 300 секунд. Чи є ще ідеї, щоб виправити це?
Патрос

15

Якщо ви хочете збільшити або додати обмеження часу для всіх сайтів, ви можете додати нижче рядки до nginx.confфайлу.

Додайте рядки нижче до httpрозділу /usr/local/etc/nginx/nginx.confабо /etc/nginx/nginx.confфайлу.

fastcgi_read_timeout 600;
proxy_read_timeout 600;

Якщо вищезазначених рядків у confфайлі не існує, додайте їх, інакше збільште fastcgi_read_timeoutі proxy_read_timeoutпереконайтеся, що nginx та php-fpm не закінчилися.

Щоб збільшити часовий ліміт лише для одного сайту, ви можете редагувати in vim /etc/nginx/sites-available/example.com

location ~ \.php$ {
    include /etc/nginx/fastcgi_params;
        fastcgi_pass  unix:/var/run/php5-fpm.sock;
    fastcgi_read_timeout 300; 
}

а після додавання цих рядків до nginx.confне забудьте перезапустити nginx.

service php7-fpm reload 
service nginx reload

або, якщо ви використовуєте камердинер, просто введіть valet restart.


1
Дякую за мене:fastcgi_read_timeout 600; proxy_read_timeout 600;
Алехандро

13

Ви також можете зіткнутися з цією ситуацією, якщо ваш сервер вище за течією використовує доменне ім’я, а його IP-адреса змінюється (наприклад: ваш верхній потік вказує на AWS Elastic Load Balancer)

Проблема полягає в тому, що nginx одноразово вирішить IP-адресу та збереже її в кешованому режимі для наступних запитів, поки конфігурація не буде перезавантажена.

Ви можете сказати nginx використовувати сервер імен для повторного вирішення домену після закінчення терміну кешування:

location /mylocation {
    # use google dns to resolve host after IP cached expires
    resolver 8.8.8.8;
    set $upstream_endpoint http://your.backend.server/;
    proxy_pass $upstream_endpoint;
}

Документи на proxy_pass пояснюють, чому цей трюк працює:

Значення параметра може містити змінні. У цьому випадку, якщо адреса вказана як доменне ім'я, ім'я шукається серед описаних груп серверів і, якщо його не знайдено, визначається за допомогою роздільної здатності.

Kudos для "Nginx з динамічними висхідними потоками" (tenzer.dk) для детального пояснення, яке також містить деяку відповідну інформацію щодо застереження цього підходу щодо перенаправлених URI.


1
ця відповідь золота, саме те, що зі мною трапилось. вгору за течією вказує на ліктьовий кінець і весь раптовий тайм-аут шлюзу.
Натан До

2

Була така ж проблема. Виявилося, це було викликано відстеженням iptables з'єднання на верхньому сервері. Після видалення --state NEW,ESTABLISHED,RELATEDсценарію брандмауера та conntrack -Fпомилки з проблемою не було.


0

Сама по собі NGINX не може бути першопричиною.

ЯКЩО "мінімальний порт на екземпляр VM", встановлений на шлюзі NAT - який стоїть між вашим екземпляром NGINX та proxy_passпунктом призначення - занадто малий для кількості одночасних запитів, його потрібно збільшити.

Рішення: збільшити доступну кількість портів на VM на NAT Gateway.

Контекст У моєму випадку в Google Cloud, зворотний проксі-сервер NGINX був розміщений всередині підмережі з NAT шлюзом. Екземпляр NGINX перенаправляв запити до домену, асоційованого з нашим API резервного інтерфейсу (вище за течією) через шлюз NAT.

Ця документація від GCP допоможе вам зрозуміти, наскільки NAT має відношення до часу очікування NGINX 504.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.