ป้องกันการหมดเวลาของเกตเวย์ nginx 504 โดยใช้ PHP set_time_limit ()


117

ฉันได้รับข้อความการหมดเวลา 504 จาก nginx เมื่อสคริปต์ PHP ของฉันทำงานนานกว่าปกติ set_time_limit(0)ดูเหมือนจะป้องกันไม่ได้! ไม่ทำงานเมื่อรัน php5-fpm บน nginx? ถ้าเป็นเช่นนั้นวิธีการตั้งเวลาที่เหมาะสมคืออะไร?

ข้อผิดพลาด:

504 Gateway Time-out
nginx/1.2.7

คำตอบ:


194

มีหลายวิธีที่คุณสามารถตั้งค่าการหมดเวลาสำหรับ php-fpm ใน/etc/php5/fpm/pool.d/www.confฉันได้เพิ่มบรรทัดนี้:

request_terminate_timeout = 180

นอกจากนี้ใน/etc/nginx/sites-available/defaultฉันได้เพิ่มบรรทัดต่อไปนี้ในบล็อกตำแหน่งของเซิร์ฟเวอร์ที่เป็นปัญหา:

fastcgi_read_timeout 180;

บล็อกตำแหน่งทั้งหมดมีลักษณะดังนี้:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_read_timeout 180;
    include fastcgi_params;
} 

ตอนนี้เพียงรีสตาร์ท php-fpm และ nginx และไม่ควรมีการหมดเวลาอีกต่อไปสำหรับคำขอที่ใช้เวลาน้อยกว่า 180 วินาที


2
ในกรณีที่มีใครสงสัยค่าเริ่มต้นของฉัน (nginx + php5-fpm) คือ 60 วินาทีดังนั้นหากคุณเห็น "การหมดเวลาของเกตเวย์" สำหรับสคริปต์ที่ 60 วินาทีควรเพิ่มการตั้งค่า "fastcgi_read_timeout"
Michael Nguyen

1
ฉันพยายามคิดหาสิ่งนี้มาหลายวันแล้วและคำตอบของ @pymkin คือสิ่งที่เหมาะกับฉัน สำหรับมือสมัครเล่นคนอื่น ๆ เช่นฉันที่สงสัยว่าจะรีสตาร์ท nginx และ php5-fpm ได้อย่างไรให้เรียกใช้สองคำสั่งต่อไปนี้: sudo service nginx restart & sudo service php5-fpm restart สิ่งเดียวที่ฉันทำแตกต่างออกไปคือฉันใช้การตั้งค่าเหล่านี้กับหนึ่งในเท่านั้น เว็บไซต์ของฉันแทนที่จะกำหนดค่าสำหรับเว็บไซต์ทั้งหมดบนเซิร์ฟเวอร์ของฉัน
Pamela

4
น่าเศร้าที่ไม่ว่าฉันfastcgi_read_timeoutจะตั้งค่าอะไรในlocationบล็อกนั้นมันก็ยังคงหมดเวลาหลังจากผ่านไป 60 วินาที
Spencer Williams

นี่ควรเป็นคำตอบที่ยอมรับได้ ลองใช้วิธีแก้ปัญหามากมาย แต่ใช้ได้ผลเท่านั้น ฉันใช้ laravel homestead และมีข้อผิดพลาดการหมดเวลาของเกตเวย์ 504 และสิ่งนี้ได้รับการแก้ไขแล้ว
Anbu369

หากใช้ Laravel คุณต้องตั้งค่านี้ในlocationบล็อกที่จัดการกับสคริปต์ php แทนที่จะเป็น docroot
Ryan DuVal

50

ลองใช้ลิงก์นี้ซึ่งมีวิธีแก้ไขที่ดีกว่าในการแก้ไขปัญหานี้ ดังนั้นขั้นตอนคือ:

  1. เปิดnginx.confไฟล์ของคุณที่อยู่ใน/etc/nginxไดเร็กทอรี
  2. เพิ่มโค้ดด้านล่างนี้ในhttp {ส่วน:

    client_header_timeout 3000;
    client_body_timeout 3000;
    fastcgi_read_timeout 3000;
    client_max_body_size 32m;
    fastcgi_buffers 8 128k;
    fastcgi_buffer_size 128k;

    หมายเหตุ: หากมีอยู่แล้วให้เปลี่ยนค่าตาม

  3. โหลด Nginx และ php5-fpm อีกครั้ง

    $ service nginx reload
    $ service php5-fpm reload

    หากข้อผิดพลาดยังคงมีอยู่ให้พิจารณาเพิ่มค่า


1
สิ่งนี้ไม่สามารถหาสาเหตุได้ แต่เพียงแค่เพิ่มเวลาจนกระทั่งเกิดข้อผิดพลาด แต่ที่ดีกว่าคือการหาวิธีแก้ปัญหาว่าทำไมโหลดนานจัง เมื่ออยู่ใน localhost ฉันเป็นไคลเอนต์เดียวและมันโหลดนานมากซึ่งไม่ดีเลยที่จะรอในขณะพัฒนา
DariusV

16
คำถามไม่ได้ถามถึงสาเหตุของสคริปต์ที่ช้า แต่กำลังถามหาวิธีทำให้เซิร์ฟเวอร์รอนานขึ้น บางครั้งคุณต้องเรียกใช้สคริปต์พิเศษที่ทำงานที่ใช้เวลานานมากและนั่นก็ไม่ใช่เรื่องเลวร้าย
ออร์ด

อัปเดต (ด้านบน) ลิงค์: codetweet.com/nginx/…
nadavkav

2
สำหรับผู้ที่อาจสงสัยว่าอะไรจะต้องใช้เวลามากพอสมควรตัวอย่างเช่นสคริปต์การติดตั้งจากเว็บอินเทอร์เฟซที่พยายามเชื่อมต่อกับฐานข้อมูลจากนั้นสร้างตารางเริ่มต้นจำนวนมากและเติมข้อมูลลงไป .. อาจใช้เวลาพอสมควรก่อนที่จะตอบสนอง
imme

/etc/nginx/sites-available/mysite.comเก็บไว้ในใจการตั้งค่าระดับโลกเหล่านี้จะถูกแทนที่โดยการตั้งค่าต่อเว็บไซต์ใน
Mac

11

คุณไม่สามารถใช้ PHP เพื่อป้องกันการหมดเวลาที่ออกโดย nginx

ในการกำหนดค่า Nginx เพื่อให้มีเวลาเพิ่มเติมโปรดดูที่สั่งproxy_read_timeout


สิ่งนี้ช่วยแก้ปัญหาที่ฉันประสบโดยที่ยุค 504 จะเริ่มปรากฏบนกล่องคนจรจัดของฉัน (โดยใช้ vaprobash)
Andy Fleming

2
ฉันเชื่อว่าคำตอบนี้ใช้ได้ก็ต่อเมื่อคุณใช้ Nginx เป็นพร็อกซีเซิร์ฟเวอร์เท่านั้น สิ่งนี้จะไม่ได้ผลหากคุณใช้ Nginx เป็นเว็บเซิร์ฟเวอร์หลัก (ด้วย PHP-FPM)
ออร์

10

คำตอบที่ถูกต้องคือการเพิ่มfastcgi_read_timeoutในการกำหนดค่า Nginx ของคุณ
ง่ายๆแค่นั้นเอง!


7
 sudo nano /etc/nginx/nginx.conf

เพิ่มตัวแปรเหล่านี้ในไฟล์ nginx.conf:

http {  
  # .....
  proxy_connect_timeout       600;
  proxy_send_timeout          600;
  proxy_read_timeout          600;
  send_timeout                600;
}

จากนั้นรีสตาร์ท:

service nginx reload

4

การหมดเวลามีสามประเภทที่อาจเกิดขึ้นในกรณีนี้ จะเห็นได้ว่าแต่ละคำตอบมุ่งเน้นไปที่แง่มุมเดียวของความเป็นไปได้เหล่านี้ ดังนั้นฉันคิดว่าจะเขียนมันลงไปเพื่อให้คนที่มาที่นี่ในอนาคตไม่จำเป็นต้องสุ่มตรวจคำตอบแต่ละข้อและได้รับความสำเร็จโดยไม่รู้ว่าข้อใดได้ผล

  1. หมดเวลาการร้องขอจากผู้ร้องขอ - ต้องตั้งค่าส่วนหัวการหมดเวลา (ดูการกำหนดค่าส่วนหัวในไลบรารีที่ร้องขอ)
  2. หมดเวลาจากnginx ขณะทำการร้องขอ (ก่อนส่งต่อไปยังเซิร์ฟเวอร์พร็อกซี) เช่นไฟล์ขนาดใหญ่ที่กำลังอัพโหลด
  3. หมดเวลาหลังจากส่งต่อไปยังเซิร์ฟเวอร์พร็อกซีเซิร์ฟเวอร์จะไม่ตอบกลับ nginx ทันเวลา เช่น: สคริปต์ที่ใช้เวลานานในการทำงานที่เซิร์ฟเวอร์

ดังนั้นการแก้ไขสำหรับแต่ละปัญหามีดังนี้

  1. ตั้งค่าส่วนหัวการหมดเวลาเช่น: ใน ajax

$.ajax({
    url: "test.html",
    error: function(){
        // will fire when timeout is reached
    },
    success: function(){
        //do something
    },
    timeout: 3000 // sets timeout to 3 seconds
});

  1. nginx ไคลเอนต์หมดเวลา

    http{
         #in seconds
        fastcgi_read_timeout 600;
        client_header_timeout 600;
        client_body_timeout 600;
     }
  2. หมดเวลาเซิร์ฟเวอร์ nginx proxied

    http{
      #Time to wait for the replying server
       proxy_read_timeout 600s;
    
    }

ดังนั้นใช้สิ่งที่คุณต้องการ ในบางกรณีคุณอาจต้องกำหนดค่าเหล่านี้ทั้งหมด ฉันต้องการ.


1

คุณต้องเพิ่มคำสั่ง nginx พิเศษ (สำหรับngx_http_proxy_module) ในnginx.confเช่น:

proxy_read_timeout 300;

โดยทั่วไปproxy_read_timeoutคำสั่งnginx จะเปลี่ยนการหมดเวลาของพร็อกซีซึ่งFcgidIOTimeoutเป็นสคริปต์ที่เงียบนานเกินไปและFcgidBusyTimeoutสำหรับสคริปต์ที่ใช้เวลาดำเนินการนานเกินไป

นอกจากนี้หากคุณใช้แอปพลิเคชัน FastCGI ให้เพิ่มตัวเลือกเหล่านี้ด้วย:

FcgidBusyTimeout 300
FcgidIOTimeout 250

จากนั้นโหลด nginx และ PHP5-FPM ใหม่

Plesk

ใน Plesk คุณสามารถเพิ่มในการตั้งค่า Web Serverภายใต้คำสั่ง Nginx เพิ่มเติม

สำหรับการตรวจสอบ FastCGI ในการตั้งค่า Web Serverภายใต้คำสั่งเพิ่มเติมสำหรับ HTTP

ดู: วิธีแก้ไขปัญหาการหมดเวลา FastCGI ใน Plesk


ไม่มีFcgidBusyTimeoutตัวแปรสำหรับ Apache เท่านั้นหรือ
Slavik

0

เนื่องจากคุณใช้ php-fpm คุณควรใช้ประโยชน์จาก fastcgi_finish_request () สำหรับการประมวลผลคำขอที่คุณทราบว่าอาจใช้เวลานานกว่านี้


-1

การใช้set_time_limit(0)จะไร้ประโยชน์เมื่อใช้ php-fpm หรือตัวจัดการกระบวนการที่คล้ายกัน

Bottomline ไม่ได้ที่จะใช้set_time_limitเมื่อมีการใช้php-fpmเพื่อเพิ่มหมดเวลาการดำเนินการของคุณตรวจสอบนี้กวดวิชา


8
อาจให้คำอธิบายบางส่วนของคำตอบที่นี่และคำตอบนี้อาจล้าสมัยหากลิงก์หมดอายุ
Lakshmi

-7

ฉันแก้ปัญหานี้ด้วย config APACHE! วิธีการทั้งหมด (ในหัวข้อนี้) ไม่ถูกต้องสำหรับฉัน ... จากนั้นฉันลอง chanche apache config:

Timeout 3600

แล้วสคริปต์ของฉันก็ใช้ได้!


5
คำถามระบุ nginx หากคุณมีปัญหากับ apache คุณควรค้นหาสิ่งนั้น
hogan

คำถามอยู่ที่ Nginx และ php-fpm ไม่ใช่ Apache
Kevin Kaburu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.