2016-04-12 20 views
13

Chạy nginx 1.9 */PHP 7.0 * (nhưng hành vi chính xác như nhau trong 5,6 * cũng có.)Nginx/PHP FPM dừng duyên dáng (SIGQUIT): không quá duyên dáng

Cố gắng một cách duyên dáng ngăn chặn một PHP-FPM /.. nginx combo cho nút tắt máy trong quá trình bảo trì. Để làm điều này, tôi sẽ gửi SIGQUIT tới php-fpm, trong đó nên cung cấp tắt máy duyên dáng.

Để kiểm tra điều này, tôi đã thực hiện một kịch bản ngớ ngẩn

<?php sleep(5); echo 'done'; 

Tested tại địa phương như sau curl

curl -I x.x.x.x:8080 

nào thường sẽ cho kết quả:

HTTP/1.1 200 OK 
Server: nginx 
Date: Tue, 12 Apr 2016 04:48:00 GMT 
Content-Type: text/html; charset=UTF-8 
Connection: close 

mong muốn: trong giữa bất kỳ yêu cầu nào trong chuyến bay, khi yêu cầu tắt máy duyên dáng, yêu cầu hiện tại sẽ kết thúc, nhưng mọi yêu cầu bổ sung sẽ không thành công.

Thật không may, khi tôi cố gắng để kích hoạt hành vi này, bằng cách gửi một SIGQUIT (http://manpages.ubuntu.com/manpages/precise/man8/php5-fpm.8.html) đến quá trình tổng PHP-FPM:

kill -s SIGQUIT $FPMPID 

Kết nối ngay giọt, dẫn đến một ngnix 502

HTTP/1.1 502 Bad Gateway 
Server: nginx 
Date: Tue, 12 Apr 2016 04:48:07 GMT 
Content-Type: text/html 
Content-Length: 166 
Connection: close 

Bạn có lời khuyên nào không? Tôi rất thích làm cho phần này của hệ thống liền mạch nhất có thể. Cảm ơn!

+0

Liên kết được đính kèm khá chết (503), tín hiệu quá trình được tóm tắt ở đây: https://forum.nginx.org/read.php?3,3485,template=head%3F%3F. –

+3

Đúng. https://bugs.php.net/bug.php?id=41593 và, cho tôi thậm chí quan trọng-er, ** https: //bugs.php.net/bug.php? id = 60961 **. Tôi không biết làm thế nào chính xác (và nếu) chúng có liên quan, nhưng PHP-FPM tiếc là có ít phiền toái của nó. – Smuuf

+0

Tôi có thể đề xuất một chút cách giải quyết cho bạn. Nó không sửa chữa php-fpm, nhưng giúp trả lời 200 :) Tất cả những gì bạn cần là thiết lập 'upstream' trong cấu hình nginx với 2-3 backends (nó có thể là cùng một nhóm php-fpm vài lần). Vì vậy, nếu một trong các yêu cầu thất bại, nginx sẽ cố gắng yêu cầu phụ trợ một lần nữa. –

Trả lời

1

Sau khi đấu tranh với tình huống tương tự này một lúc, tôi tin rằng tôi đã tìm thấy cài đặt cấu hình phép thuật để làm cho các tiến trình con xử lý xong các yêu cầu trước khi chết.

http://php.net/manual/en/install.fpm.configuration.php#process-control-timeout

process_control_timeout

Thời hạn tiến trình con để chờ đợi một phản ứng trên tín hiệu từ tổng thể

Về cơ bản, bằng cách thiết lập này để một cái gì đó giống như 10s, đứa trẻ quá trình sẽ chờ đợi lâu, trong khi xử lý các yêu cầu hiện có trước khi thoát.

Thật không may, có vẻ như quá trình php-fpm chủ thoát ngay lập tức, vì vậy, lấy cảm hứng từ các mã here, tôi đã viết một kịch bản wrapper:

#!/bin/bash 

PHP_FPM_PID='/php-fpm.pid' 

wait_for_pid() { 
    try=0 

    while test $try -lt 35 ; do 
     if [ ! -f "$1" ] ; then 
      try='' 
      break 
     fi 

     echo -n . 
     try=`expr $try + 1` 
     sleep 1 
    done 
} 

function clean_up { 

    echo "Killing $(cat $PHP_FPM_PID)" 

    kill -QUIT `cat $PHP_FPM_PID` 
    wait_for_pid $PHP_FPM_PID 

    echo "Done!" 

    exit 0 
} 

trap clean_up EXIT 

nohup php-fpm --daemonize --pid $PHP_FPM_PID 2>&1 & 

while true; do sleep 1; done 
#^do nothing forever 

mà đợi 35 giây hoặc cho đến khi tập tin pid đã được gỡ bỏ (có lẽ là do một trong các quy trình con? Tôi vẫn chưa rõ ràng trên cách xóa).

Bất kể, tập lệnh trình bao bọc này hoạt động tốt như CMD cho vùng chứa docker php-fpm của chúng tôi mà chúng tôi đang chạy với Kubernetes.

+1

Có vẻ như một cài đặt hữu ích, nhưng điều này có nghĩa là nó * luôn luôn * đợi X giây trước khi trả lời? Tôi đã loại bỏ quá trình này cho container docker của tôi (https://github.com/bryanlatten/docker-php), thay vì ngay lập tức báo hiệu fpm để tắt một cách duyên dáng, tôi duyên dáng tắt proxy nginx về phía trước của nó - điều này sẽ được duyên dáng và chờ kết nối hoàn thành. Về lý thuyết, không có kết nối đến, và các kết nối gửi đi chờ đợi gần, PHP sau đó có thể chấm dứt như một con voi và không có gì trong chuyến bay nên bị ảnh hưởng. Điều này có nghĩa không? –

+0

Tuyệt đối, tôi nghĩ rằng việc sử dụng nginx như một proxy tắt máy duyên dáng ở đây là giải pháp đúng. Nó sẽ không làm việc cho chúng tôi thật không may, nhưng tôi nghĩ đó là con đường để đi trong tương lai. –

Các vấn đề liên quan