Apache2 Proxy timeout

23

Saya memiliki Apache2 dengan PHP + PHP-FPM yang dikonfigurasi sesuai dengan:

http://wiki.apache.org/httpd/PHP-FPM

Saya menulis sebuah skrip yang akan membutuhkan waktu lama untuk dieksekusi pada Vhost internal, tetapi terus waktunya, semuanya berjalan dengan sempurna jika skrip dijalankan dalam waktu kurang dari 30 detik.

Log apache saya memberi tahu saya:

[Wed Apr 17 21:57:23.075175 2013] [proxy_fcgi:error] [pid 9263:tid 140530454267648] (70007)The timeout specified has expired: [client 58.169.202.172:49017] AH01075: Error dispatching request to :, referer:

Saat mencoba menjalankan skrip, saya diberikan 503 Service Unavailablewaktu eksekusi tepat 30 detik. Secara logis ini berarti saya memiliki arahan batas waktu atau pengaturan yang diatur ke 30 detik, tetapi saya memilikinya di konfigurasi Vhost saya:

Timeout 600
<IfModule proxy_module>
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/home/pyrokinetiq/scripts/$1 timeout=600
    ProxyTimeout 600
</IfModule>

(php-fpm berjalan pada port 9001 untuk saya)

Saya juga telah mencoba menempatkan Timeoutdan ProxyTimeoutdi httpd.confdengan tidak ada perbedaan.

Tampaknya ada pengaturan batas waktu lain di suatu tempat yang khusus untuk mod_proxy_fcgi, tetapi saya tidak dapat menemukannya. Saya menginstal Apache2 httpd dari tarball resmi, tidak ada mod yang tampaknya datang dengan file konfigurasi.

Kalau ada yang bisa mengarahkan saya ke arah yang benar itu akan sangat dihargai.

wyqydsyq
sumber

Jawaban:

32

Saya akhirnya memperbaiki masalah ini setelah menguji beberapa parameter konfigurasi. Saya menguji solusi dua kali, menghapus semua perubahan sebelumnya. Hanya satu parameter yang diperlukan bagi saya untuk memperbaikinya.

Untuk versi terbaru dari httpd dan mod_proxy_fcgi Anda cukup menambahkan timeout=ke akhir ProxyPassMatchbaris, misalnya:

ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1 timeout=1800

Untuk versi yang lebih lama, ini sedikit lebih rumit, misalnya:

<Proxy fcgi://127.0.0.1:9000>
  ProxySet timeout=1800
</Proxy>
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1

Saya perlu menambahkan arahan Proxy untuk mengatur batas waktu hingga 30 menit. Dalam beberapa aplikasi, biasanya ketika mengoperasikan basis data, ada rutinitas yang dapat memakan waktu lebih dari 10 menit untuk dijalankan. Saya sementara mengatur batas waktu menjadi 30 menit untuk memastikan mereka selesai. Berguna secara khusus ketika menggunakan wizard instalasi, yang membutuhkan terlalu banyak waktu (menurut pendapat saya).

Omong-omong input awal yang membantu saya untuk memecahkan masalah ini ditemukan di alamat URL berikut .

Jordi Ferran
sumber
1
Sepertinya ini rusak di bawah versi terbaru dari Apache, AH00526: ProxyPass / <Proxy> dan ProxyPassMatch / <ProxyMatch> tidak dapat digunakan sama sekali dengan nama pekerja yang sama
Stewart Adam
4
Saya telah menyelesaikan hal di atas dengan menambahkan parameter 'timeout = 120' di akhir baris ProxyPassMatch.
Stewart Adam
@Palantir senang mendengarnya! Diserahkan sebagai jawaban .
Stewart Adam
Dua hal lagi yang saya butuhkan: Pertama, Anda harus menyetel "Timeout" dan "ProxyTimeout" di file konfigurasi apache global Anda menjadi lebih lama daripada timeout FPM lainnya. Kedua, kumpulan FPM saya mendengarkan pada soket unix dan saya menggunakan SetHandler seperti: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "]. Tetapi <Proxy> cocok dengan fcgi: // localhost bagian dari garis SetHandler (bagian SETELAH | ... yang bahkan tidak benar-benar digunakan!) Dan BUKAN bagian unix: / var / run /. jadi untuk mengkonfigurasi batas waktu penggunaan di atas: <Proxy fcgi: // localhost: 8000> dan bukan <Proxy unix: / var / run / ...
Professor Falken
9

Saya ingin menunjukkan bahwa walaupun jawaban ini bekerja dengan baik untuk versi yang lebih lama, itu rusak di bawah versi terbaru dari Apache 2.4 dengan kode kesalahan AH00526. ProxyPassdan ProxyPassMatchatau <Proxy>dan <ProxyMatch>tidak dapat digunakan bersama dalam nama pekerja yang sama. Ini digunakan untuk berfungsi dengan baik, jadi tidak tahu apakah itu diubah oleh desain atau apakah itu bug.

Apa pun itu, Anda dapat memperbaikinya dengan hanya menggunakan ProxyPassMatch dengan parameter 'batas waktu = 120' (atau apa pun nilai yang Anda inginkan), mis::

ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
Stewart Adam
sumber
6

Saya memiliki Apache 2.4.6, tetapi tambalan untuk memperbaikinya disediakan di Apache> = 2.4.8. Kuncinya di sini adalah untuk memulai output Anda segera sehingga Apache (mod_proxy_fcgi) menganggap koneksi sedang aktif.

Misalnya, saya menggunakan PHP dan permintaan DB untuk panggilan AJAX saya membutuhkan> 30 detik. Karena saya tahu bahwa respons keseluruhan akan menjadi "Tipe Konten: aplikasi / json", saya segera mengirim tajuk itu.

#1: Start output immediately
#Note: Sending the header is innocuous
#   it can be changed later using the $replace parameter
#   (see #3)
header( 'Content-Type: application/json' );

#2: Run slow query
mysql_query( "SELECT * FROM giant_table" );

#3: Change header as needed
header( 'Content-Type: application/csv', true );

#output content
Chris
sumber
2

Bukankah seharusnya:

<IfModule mod_proxy.c>

Pastikan pengaturan php.ini max_execution_time diatur ke 600 juga. (periksa phpinfo () di laman langsung untuk memastikan Anda melihat nilai aktual yang digunakan)

Seperti kata Jenny, atur pengaturan php-fpm

request_terminate_timeout 610s

(catat di akhir)

Tidak banyak yang bisa dikonfigurasikan dengan mod_proxy_fcgi sendiri, seperti yang Anda lihat di halaman apache. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Aktifkan debug debug php-fpm juga sehingga Anda dapat melihat di mana waktu di luar sana. http://php-fpm.org/wiki/Configuration_File (aktifkan juga catch_workers_output)

Dan nyalakan debug level logging untuk modul mod_proxy dan mod_proxy_fcgi karena Anda menggunakan apache 2.4. Fitur yang sangat bagus, nyalakan hanya untuk modul yang Anda butuhkan: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Jika itu tidak membantu, kirim file konfigurasi php-fpm Anda.

Sebagai upaya terakhir, mungkin beberapa daemon membunuh proses yang berjalan lama?

tukang makan
sumber
2

Saya mencatat bahwa Anda menggunakan PHP-FPM. Saya juga menggunakannya, tetapi dengan Apache 2.4.6.

Dengan asumsi bahwa masalah telah ada selama beberapa waktu, tampaknya nilai batas waktu untuk itu mod_proxy_fcgiadalah kode sulit . Saya menulis apa yang saya temukan di sini

tuanich
sumber
1

Karena Anda telah memperbaiki pengaturan waktu tunggu di apache, itu seharusnya tidak menjadi masalah. Tempat kedua untuk dilihat adalah peralatan jaringan apa pun, tetapi karena Anda melakukan proxy ke server Anda sendiri, itu juga tidak mungkin. Jadi tempat yang tersisa untuk melihat adalah di server backend.

Ih file konfigurasi untuk php-pfm, cari

; This is a hard kill switch on php execution.  It ignores the
; max_execution_time that can be set/changed with php_ini.  Basically
; it avoids timeout issues between apache and php-fpm.
request_terminate_timeout=30

Ini harus diatur ke yang sama dengan, atau sedikit di bawah, pengaturan batas waktu di apache.

Jenny D kata Reinstate Monica
sumber
1
Saya telah menetapkan request_terminate_timeoutke 400, masih tidak ada perubahan :( Saya punya perasaan bahwa ada sesuatu yang perlu saya atur mod_proxy_fcgi, tetapi sepertinya tidak datang dengan file konfigurasi.
wyqydsyq
0

Selain batas waktu, setel enablereuse = off. Saya menemukan ketika itu pada beberapa permintaan untuk skrip yang berjalan lama akan bekerja dengan benar dan yang lainnya akan dibunuh lebih awal.

ctlq
sumber
0

Posting ini mengubah seluruh kesepakatan untuk saya.

Sepertinya mod_reqtimeout dari Apache tidak akan menggunakan nilai default.

Tambahkan baris berikut ke file httpd.conf Anda :

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
Frosty Z
sumber