Proksi terbalik Nginx menyebabkan 504 Gateway Timeout

130

Saya menggunakan Nginx sebagai reverse proxy yang mengambil permintaan kemudian melakukan proxy_pass untuk mendapatkan aplikasi web sebenarnya dari server upstream yang berjalan pada port 8001.

Jika saya membuka mywebsite.com atau melakukan wget, saya mendapatkan 504 Gateway Timeout setelah 60 detik ... Namun, jika saya memuat mywebsite.com:8001, aplikasi akan dimuat seperti yang diharapkan!

Jadi ada sesuatu yang mencegah Nginx berkomunikasi dengan server upstream.

Semua ini dimulai setelah perusahaan hosting saya mengatur ulang mesin tempat barang saya berjalan, sebelum itu tidak ada masalah apa pun.

Ini blok server vhosts saya:

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;
    }
} 

Dan output dari log kesalahan Nginx saya:

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"
Dave Roma
sumber
Apakah server menjalankan SELinux?
CrackerJack9
DALAM KASUS SAYA, gateway NAT adalah masalahnya, bukan NGINX atau API backend. stackoverflow.com/a/62351959/9956279
Sushilinux

Jawaban:

152

Mungkin dapat menambahkan beberapa baris lagi untuk menambah periode waktu tunggu ke hulu. Contoh di bawah menyetel batas waktu menjadi 300 detik:

proxy_connect_timeout       300;
proxy_send_timeout          300;
proxy_read_timeout          300;
send_timeout                300;
pengguna2540984
sumber
5
Saya pikir menambah waktu tunggu jarang merupakan jawaban kecuali Anda tahu jaringan / layanan Anda akan selalu atau dalam beberapa kasus merespons dengan sangat lambat. Beberapa permintaan web saat ini seharusnya memakan waktu lebih dari beberapa detik kecuali Anda mengunduh konten (file / gambar)
Almund
@Almund Saya memikirkan hal yang sama (hampir tidak repot-repot mencoba ini), tetapi untuk alasan apa pun ini hanya berhasil untuk saya. (Sebelumnya waktu habis setelah 60 detik, sekarang dapatkan tanggapan segera).
Dax Fohl
@Dax Fohl: Itu penasaran. Saya menarik ke bawah sumber dan melihat sekilas dan dari apa yang saya lihat, mengatur pengaturan proxy_ selain dari proxy_pass akan menginisialisasi banyak pengaturan yang saya anggap akan menjalankan proxy dengan cara yang berbeda jadi mungkin pengaturan apa pun akan memberikan hal yang sama tingkah laku.
Almund
Tidak menyelesaikan masalah karena saya menggunakannya dengan server
nodejs
3
Saya menemukan bahwa saya hanya perlu proxy_read_timeoutsaat debugging di backend. Terima kasih!
Jeff Puckett
79

Meningkatkan batas waktu kemungkinan tidak akan menyelesaikan masalah Anda karena, seperti yang Anda katakan, server web target yang sebenarnya merespons dengan baik.

Saya memiliki masalah yang sama dan saya menemukan itu ada hubungannya dengan tidak menggunakan keep-hidup pada koneksi. Saya tidak dapat benar-benar menjawab mengapa ini terjadi tetapi, dalam membersihkan tajuk koneksi saya menyelesaikan masalah ini dan permintaan itu diproksikan dengan baik:

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;
    }
}

Lihatlah posting ini yang menjelaskannya secara lebih rinci: nginx menutup koneksi upstream setelah permintaan Klarifikasi header Keep-hidup http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

Almund
sumber
7
BULAN masalah diselesaikan dengan satu baris proxy_set_header Connection "";lol, jangan gunakan runcloud
nodws
22

user2540984 , serta banyak lainnya telah menunjukkan bahwa Anda dapat mencoba meningkatkan pengaturan waktu tunggu Anda. Saya sendiri menghadapi masalah serupa dengan yang satu ini dan mencoba mengubah pengaturan batas waktu saya di file /etc/nginx/nginx.conf , seperti yang disarankan oleh hampir semua orang di utas ini. Ini, bagaimanapun, tidak membantu saya sedikit pun; tidak ada perubahan yang jelas dalam pengaturan batas waktu NGINX. Setelah berjam-jam mencari, saya akhirnya berhasil menyelesaikan masalah saya.

Solusinya terletak pada utas forum ini , dan yang dikatakannya adalah Anda harus meletakkan pengaturan batas waktu di /etc/nginx/conf.d/timeout.conf (dan jika file ini tidak ada, Anda harus membuatnya). Saya menggunakan pengaturan yang sama seperti yang disarankan di utas:

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

Ini mungkin bukan solusi untuk masalah khusus Anda, tetapi jika ada orang lain yang memperhatikan bahwa perubahan batas waktu di /etc/nginx/nginx.conf tidak melakukan apa-apa, saya harap jawaban ini membantu!

Andreas Forslöw
sumber
hai tidak ada timeout.conf di direktori config.d saya. Anda berkata buat itu, dan saya ingin mengonfirmasi, cukup tambahkan pengaturan di atas di timeout.conf?
tktktk0711
Ya, tambahkan saja. Anda dapat memodifikasinya untuk kebutuhan Anda sendiri, tetapi ini berhasil untuk saya!
Andreas Forslöw
Sayangnya, di homestead Laravel dengan ubuntu dan Nginx, ini tidak berfungsi. :( Maksud Anda hanya menambahkan baris itu? Tanpa server{}atau yang lain? Kesalahan ini muncul tepat setelah 5 menit. Saya memuat ulang, memulai ulang, dan tidak pernah berhasil melewati 5 menit atau 300 detik tersebut. Adakah ide lain yang harus diperbaiki itu?
Pathros
15

Jika Anda ingin menambah atau menambah batas waktu ke semua situs maka Anda dapat menambahkan baris di bawah ini ke nginx.conffile.

Tambahkan baris di bawah ini ke httpbagian /usr/local/etc/nginx/nginx.confatau /etc/nginx/nginx.conffile.

fastcgi_read_timeout 600;
proxy_read_timeout 600;

Jika baris di atas tidak ada dalam conffile, tambahkan, jika tidak tambah fastcgi_read_timeoutdan proxy_read_timeoutpastikan bahwa nginx dan php-fpm tidak timeout.

Untuk menambah batas waktu hanya untuk satu situs maka sobat dapat mengedit di 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; 
}

dan setelah menambahkan baris ini nginx.conf, jangan lupa restart nginx.

service php7-fpm reload 
service nginx reload

atau, jika Anda menggunakan valet, cukup ketik valet restart.

Adeel
sumber
1
Terima kasih untuk saya:fastcgi_read_timeout 600; proxy_read_timeout 600;
Alejandro
13

Anda juga dapat menghadapi situasi ini jika server upstream Anda menggunakan nama domain, dan alamat IP-nya berubah (misalnya: upstream Anda mengarah ke AWS Elastic Load Balancer)

Masalahnya adalah nginx akan menyelesaikan alamat IP satu kali, dan menyimpannya dalam cache untuk permintaan selanjutnya hingga konfigurasi dimuat ulang.

Anda dapat memberi tahu nginx untuk menggunakan server nama untuk menyelesaikan kembali domain setelah entri yang di-cache kedaluwarsa:

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;
}

Dokumen di proxy_pass menjelaskan mengapa trik ini berhasil:

Nilai parameter dapat berisi variabel. Dalam kasus ini, jika alamat ditentukan sebagai nama domain, nama tersebut dicari di antara grup server yang dijelaskan, dan, jika tidak ditemukan, ditentukan menggunakan resolver.

Kudos to "Nginx with dynamic upstreams" (tenzer.dk) untuk penjelasan mendetail, yang juga berisi beberapa informasi relevan tentang peringatan pendekatan ini terkait URI yang diteruskan.

el.atomo
sumber
1
jawaban ini emas, persis apa yang terjadi padaku. upstream menunjuk ke aws elb dan semua waktu tunggu Gateway tiba-tiba.
Nathan Do
2

Punya masalah yang sama. Ternyata itu disebabkan oleh pelacakan koneksi iptables di server upstream. Setelah menghapus --state NEW,ESTABLISHED,RELATEDdari skrip firewall dan pembilasan dengan conntrack -Fmasalah itu hilang.

mindlab
sumber
0

NGINX sendiri mungkin bukan penyebab utamanya.

JIKA "port minimum per instance VM" yang disetel di Gateway NAT - yang berada di antara instance NGINX Anda & proxy_passtujuan - terlalu kecil untuk jumlah permintaan serentak, itu harus ditingkatkan.

Solusi: Tingkatkan jumlah port yang tersedia per VM di NAT Gateway.

Konteks Dalam kasus saya, di Google Cloud, proxy balik NGINX ditempatkan di dalam subnet, dengan Gateway NAT. Instance NGINX mengalihkan permintaan ke domain yang terkait dengan API backend kami (upstream) melalui NAT Gateway.

Dokumentasi dari GCP ini akan membantu Anda memahami relevansi NAT dengan waktu tunggu NGINX 504.

Sushilinux
sumber
-1

Dalam kasus saya, saya me-restart php dan itu menjadi ok.

Mahdy Aslamy
sumber