많은 백엔드 서버와 함께 nginx를 리버스 프록시로 설정하려고합니다. 요청시 백엔드를 시작하고 싶습니다 (첫 번째 요청에서), 요청에 따라 백엔드를 시작하는 제어 프로세스 (HTTP 요청에 의해 제어 됨)가 있습니다.
내 문제는 nginx를 구성하는 것입니다. 여기까지 내가 가진 것입니다 :
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;
}
}
nginx는 제어 서버에서 반환 된 상태 코드를 무시하는 것 같습니다. 위치 의 error_page
지시문이 @handle_502
작동하지 않으며 451 코드는 그대로 클라이언트로 전송됩니다.
나는 이것을 위해 내부 nginx 리디렉션을 사용하려고 포기하고 동일한 위치로 307 리디렉션을 내보내도록 제어 서버를 수정하려고 시도했습니다 (클라이언트는 동일한 요청을 다시 시도하지만 이제는 백엔드 서버가 시작되었습니다). 그러나 이제 nginx는 제어 서버가 "Location"헤더를 전송하고 있음에도 불구하고 백엔드 요청 시도 (502)에서 가져온 코드로 상태 코드를 어리석게 덮어 씁니다. error_page 행을 다음과 같이 변경하여 "작동"했습니다.error_page 502 =307 @handle_502;
따라서 모든 제어 서버 응답이 307 코드로 클라이언트에 다시 전송되도록합니다. 1) 제어 서버의 응답에 따라 다음에 nginx가 수행해야 할 작업에 대한 제어가 없기 때문에 (제어 서버가 성공을보고하는 경우에만 백엔드를 다시 시도하고 싶습니다) 2) 모든 HTTP가 아니기 때문에 매우 해킹 및 바람직하지 않습니다. 클라이언트는 HTTP 리디렉션을 지원합니다 (예 : curl 사용자 및 libcurl 사용 응용 프로그램은 다음 리디렉션을 명시 적으로 활성화해야 함).
nginx가 업스트림 서버 A, B, A를 다시 프록시하도록 시도하는 올바른 방법은 무엇입니까 (이상적으로 B가 특정 상태 코드를 반환 할 때만)?
proxy_next_upstream
트릭을 수행했습니다 (내 시나리오가 귀하의 시나리오만큼 복잡하지는 않았습니다). 오류가 발생하면 nginx가 다음 서버를 시도하기를 원했기 때문에proxy_next_upstream error timeout invalid_header non_idempotent;
( 요청non_idempotent
을 주로 전달하고 싶기 때문에) 추가해야했습니다POST
.