Apache2 Proxy หมดเวลา


23

ฉันมี Apache2 พร้อม PHP + PHP-FPM ที่กำหนดค่าตาม:

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

ฉันกำลังเขียนสคริปต์ที่จะต้องใช้เวลานานในการรันบน Vhost ภายใน แต่หมดเวลาหมดทุกอย่างจะทำงานได้อย่างไม่มีที่ติหากสคริปต์ทำงานภายใน 30 วินาที

บันทึก apache ของฉันบอกฉัน:

[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:

เมื่อพยายามเรียกใช้สคริปต์ฉันจะได้รับ503 Service Unavailableหลังจากระยะเวลาดำเนินการ 30 วินาที เหตุผลนี้หมายความว่าฉันมีคำสั่งหมดเวลาหรือตั้งค่าเป็น 30 วินาที แต่ฉันมีสิ่งเหล่านี้ในการกำหนดค่า Vhost ของฉัน:

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

(php-fpm ทำงานบนพอร์ต 9001 สำหรับฉัน)

ฉันยังได้พยายามวางTimeoutและProxyTimeoutในhttpd.confไม่แตกต่างกัน

ดูเหมือนว่าจะมีการตั้งค่าการหมดเวลาอีกครั้งสำหรับบางแห่งที่เฉพาะเจาะจงmod_proxy_fcgiแต่ฉันไม่สามารถหาได้ ฉันติดตั้ง Apache2 httpd จาก tarball อย่างเป็นทางการดูเหมือนว่าไม่มี mods ใดที่จะมาพร้อมกับไฟล์การกำหนดค่าใด ๆ

หากใครสามารถชี้ให้ฉันในทิศทางที่ถูกต้องมันจะได้รับการชื่นชมมาก

คำตอบ:


32

ในที่สุดฉันก็แก้ไขปัญหานี้หลังจากทดสอบพารามิเตอร์การกำหนดค่าหลายอย่าง ฉันทดสอบโซลูชันสองครั้งโดยลบการเปลี่ยนแปลงก่อนหน้านี้ทั้งหมด ฉันต้องการแก้ไขพารามิเตอร์เดียวเท่านั้น

สำหรับรุ่นล่าสุดของ httpd และ mod_proxy_fcgi คุณสามารถเพิ่มtimeout=ไปที่ท้ายProxyPassMatchบรรทัดเช่น:

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

สำหรับรุ่นเก่ามันซับซ้อนกว่าเล็กน้อยเช่น:

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

ฉันต้องการเพิ่มคำสั่ง Proxy เพื่อตั้งค่าการหมดเวลาเป็น 30 นาที ในบางแอปพลิเคชันซึ่งโดยปกติเมื่อใช้ฐานข้อมูลจะมีกิจวัตรที่อาจใช้เวลานานกว่า 10 นาทีในการดำเนินการ ฉันตั้งค่าการหมดเวลาชั่วคราวเป็น 30 นาทีเพื่อให้แน่ใจว่าเสร็จแล้ว มีประโยชน์อย่างยิ่งเมื่อใช้ตัวช่วยสร้างการติดตั้งซึ่งใช้เวลานานเกินไป (ตามความเห็นของฉัน)

โดยวิธีการป้อนข้อมูล intial ที่ช่วยให้ฉันเพื่อแก้ปัญหานี้ถูกพบในต่อไปนี้ที่อยู่ URL


1
ดูเหมือนว่ามันจะแตกภายใต้ Apache รุ่นล่าสุด AH00526: ProxyPass / <Proxy> และ ProxyPassMatch / <ProxyMatch> ไม่สามารถใช้ร่วมกับชื่อผู้ปฏิบัติงานคนเดียวกันได้
Stewart Adam

4
ฉันได้แก้ไขข้างต้นโดยการเพิ่มพารามิเตอร์ 'หมดเวลา = 120' ในตอนท้ายของบรรทัด ProxyPassMatch
Stewart Adam

@Palantir ดีใจที่ได้ยิน! ส่งเป็นคำตอบ
สจ๊วตอดัม

สิ่งที่ฉันต้องการอีกสองอย่าง: อันดับแรกคุณต้องตั้งค่า "หมดเวลา" และ "ProxyTimeout" ในไฟล์กำหนดค่า apache ส่วนกลางของคุณให้นานกว่าการหมดเวลา FPM อื่น ๆ ประการที่สองพูล FPM ของฉันฟังซ็อกเก็ต unix และฉันใช้ SetHandler อย่างนั้น: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "] แต่ <Proxy> จับคู่กับส่วน fcgi: // localhost ของบรรทัด SetHandler (ส่วนหลัง | ... ซึ่งไม่ได้ใช้จริง!) และไม่ใช่ยูนิกซ์: / var / run / part เพื่อกำหนดค่าการหมดเวลาสำหรับการใช้งานด้านบน: <Proxy fcgi: // localhost: 8000> และไม่ใช่ <Proxy unix: / var / run / ...
ศาสตราจารย์ Falken

9

ฉันต้องการชี้ให้เห็นว่าถึงแม้ว่าคำตอบนี้จะใช้ได้ดีสำหรับรุ่นเก่า แต่แบ่งภายใต้ Apache 2.4 รุ่นล่าสุดด้วยรหัสข้อผิดพลาด AH00526 ProxyPassและProxyPassMatchหรือ<Proxy>และ<ProxyMatch>ไม่สามารถใช้ร่วมกันภายในชื่อผู้ปฏิบัติงานเดียวกัน สิ่งนี้เคยทำหน้าที่ได้ดีดังนั้นจึงไม่ทราบว่ามีการเปลี่ยนแปลงโดยการออกแบบหรือว่าเป็นข้อบกพร่อง

ไม่ว่าด้วยวิธีใดคุณสามารถแก้ไขได้โดยใช้ ProxyPassMatch พร้อมกับพารามิเตอร์ 'timeout = 120' (หรือค่าที่คุณต้องการ) เช่น:

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

6

ฉันมี Apache 2.4.6 แต่แพทช์เพื่อแก้ไขมีให้ใน Apache> = 2.4.8 กุญแจสำคัญที่นี่คือการเริ่มต้นการส่งออกของคุณทันทีเพื่อให้ Apache (mod_proxy_fcgi) คิดว่าการเชื่อมต่อใช้งานได้

ตัวอย่างเช่นฉันใช้ PHP และแบบสอบถาม DB สำหรับการโทร AJAX ของฉันใช้เวลา> 30 วินาที เนื่องจากฉันรู้ว่าการตอบสนองโดยรวมจะเป็น "ประเภทเนื้อหา: application / json" ฉันจึงส่งส่วนหัวนั้นทันที

#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

2

ไม่ควรเป็น:

<IfModule mod_proxy.c>

ตรวจสอบให้แน่ใจว่าการตั้งค่า php.ini max_execution_time ตั้งไว้ที่ 600 ด้วย (ตรวจสอบ phpinfo () บนหน้าสดเพื่อให้แน่ใจว่าคุณเห็นมูลค่าจริงที่ใช้)

อย่างที่เจนนี่พูดให้ตั้งค่า php-fpm

request_terminate_timeout 610s

(บันทึก s ในตอนท้าย)

mod_proxy_fcgi นั้นมีอยู่ไม่มากที่คุณสามารถดูได้จากหน้า apache http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

เปิดใช้งานการบันทึกการดีบัก php-fpm เช่นกันเพื่อให้คุณสามารถดูว่าหมดเวลาที่ไหน http://php-fpm.org/wiki/Configuration_File (เปิด catch_workers_output ด้วย)

และเปิดการบันทึกระดับการดีบักสำหรับโมดูล mod_proxy และ mod_proxy_fcgi เนื่องจากคุณใช้ apache 2.4 คุณสมบัติที่ดีมาก ๆ เปิดสำหรับโมดูลที่คุณต้องการ: http://httpd.apache.org/docs/current/mod/core.html#loglevel

หากสิ่งเหล่านี้ไม่ช่วยให้โพสต์ไฟล์กำหนดค่า php-fpm ของคุณ

เป็นทางเลือกสุดท้ายภูตบางตัวอาจฆ่ากระบวนการที่ใช้เวลานาน?


2

ฉันสังเกตเห็นว่าคุณกำลังใช้ PHP-FPM ฉันก็ใช้มันเหมือนกัน แต่กับ Apache 2.4.6

สมมติว่าปัญหามีอยู่บางครั้งก็ดูเหมือนว่าจะเป็นไปได้ว่าค่าการหมดเวลาสำหรับการmod_proxy_fcgiจะเขียนยาก ฉันเขียนสิ่งที่ฉันพบที่นี่


1

เนื่องจากคุณได้แก้ไขการตั้งค่าไทม์เอาต์ใน apache นั่นไม่ควรเป็นปัญหา สถานที่ที่ควรมองหาอันดับที่สองคืออุปกรณ์เครือข่ายใด ๆ แต่เนื่องจากคุณพร็อกซีเซิร์ฟเวอร์ของคุณเอง ดังนั้นสถานที่ที่เหลืออยู่ให้ดูคือเซิร์ฟเวอร์ส่วนหลัง

Ih ไฟล์ config สำหรับ php-pfm ให้ค้นหา

; 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

ควรตั้งค่านี้เหมือนกับการตั้งค่าการหมดเวลาใน apache


1
ฉันได้ตั้งค่าเป็นrequest_terminate_timeout400 ยังคงไม่มีการเปลี่ยนแปลง :( ฉันมีความรู้สึกว่ามีบางสิ่งที่ฉันจำเป็นต้องตั้งค่าmod_proxy_fcgiแต่ดูเหมือนจะไม่ได้มาพร้อมกับไฟล์การตั้งค่าใด ๆ
wyqydsyq

0

นอกเหนือจากการหมดเวลาให้ตั้งค่า enablereuse = off ฉันพบว่าเมื่อมีการร้องขอสคริปต์ที่รันนาน ๆ จะทำงานได้อย่างถูกต้องและอื่น ๆ จะถูกฆ่าก่อน


0

โพสต์นี้เปลี่ยนข้อตกลงทั้งหมดสำหรับฉัน

ดูเหมือนว่าmod_reqtimeoutของ Apache จะไม่ใช้ค่าเริ่มต้น

เพิ่มบรรทัดต่อไปนี้ในไฟล์ httpd.confของคุณ:

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.