Tôi đang cố gắng thiết lập nginx như một proxy ngược, với một số lượng lớn máy chủ phụ trợ. Tôi muốn khởi động các phụ trợ theo yêu cầu (theo yêu cầu đầu tiên xuất hiện), vì vậy tôi có một quy trình kiểm soát (được kiểm soát bởi các yêu cầu HTTP) khởi động phụ trợ tùy theo yêu cầu mà nó nhận được.
Vấn đề của tôi là cấu hình nginx để làm điều đó. Đây là những gì tôi có cho đến nay:
server {
listen 80;
server_name $DOMAINS;
location / {
# redirect to named location
#error_page 418 = @backend;
#return 418; # doesn't work - error_page doesn't work after redirect
try_files /nonexisting-file @backend;
}
location @backend {
proxy_pass http://$BACKEND-IP;
error_page 502 @handle_502; # Backend server down? Try to start it
}
location @handle_502 { # What to do when the backend server is not up
# Ping our control server to start the backend
proxy_pass http://127.0.0.1:82;
# Look at the status codes returned from control server
proxy_intercept_errors on;
# Fallback to error page if control server is down
error_page 502 /fatal_error.html;
# Fallback to error page if control server ran into an error
error_page 503 /fatal_error.html;
# Control server started backend successfully, retry the backend
# Let's use HTTP 451 to communicate a successful backend startup
error_page 451 @backend;
}
location = /fatal_error.html {
# Error page shown when control server is down too
root /home/nginx/www;
internal;
}
}
Điều này không hoạt động - nginx dường như bỏ qua bất kỳ mã trạng thái nào được trả về từ máy chủ điều khiển. Không có error_page
chỉ thị nào trong @handle_502
vị trí hoạt động và mã 451 được gửi nguyên trạng cho máy khách.
Tôi đã từ bỏ việc cố gắng sử dụng chuyển hướng nginx nội bộ cho việc này và đã thử sửa đổi máy chủ điều khiển để phát ra một chuyển hướng 307 đến cùng một vị trí (để máy khách sẽ thử lại cùng một yêu cầu, nhưng bây giờ với máy chủ phụ trợ đã khởi động). Tuy nhiên, bây giờ nginx đang ngu ngốc ghi đè mã trạng thái với mã trạng thái nhận được từ lần thử yêu cầu phụ trợ (502), mặc dù máy chủ điều khiển đang gửi tiêu đề "Vị trí". Cuối cùng tôi đã làm cho nó "hoạt động" bằng cách thay đổi dòng error_page thànherror_page 502 =307 @handle_502;
, do đó buộc tất cả các phản hồi của máy chủ điều khiển phải được gửi lại cho máy khách với mã 307. Điều này rất khó khăn và không mong muốn, bởi vì 1) không có quyền kiểm soát nginx nên làm gì tiếp theo tùy thuộc vào phản hồi của máy chủ điều khiển (lý tưởng là chúng tôi chỉ muốn thử lại phần phụ trợ chỉ khi máy chủ điều khiển báo cáo thành công) và 2) không phải tất cả HTTP khách hàng hỗ trợ chuyển hướng HTTP (ví dụ: người dùng curl và các ứng dụng sử dụng libcurl cần phải bật các chuyển hướng sau một cách rõ ràng).
Cách thích hợp để khiến nginx thử proxy vào máy chủ ngược dòng A, rồi B, rồi lại A (lý tưởng nhất là khi B trả về một mã trạng thái cụ thể)?
proxy_next_upstream
thủ thuật này (kịch bản của tôi không phức tạp như của bạn), tôi chỉ muốn nginx dùng thử máy chủ tiếp theo nếu xảy ra lỗi, do đó tôi phải thêmproxy_next_upstream error timeout invalid_header non_idempotent;
(non_idempotent
vì tôi muốn chuyển tiếpPOST
yêu cầu).