nginx upstream 404 응답 sleep 후 재시도하기

# nginx 를 reverse-proxy 로 사용하는 경우
# upstream 에서 404 응답을 주면 몇초후 다시 시도하는 방법
# 우선 sleep 및 location 이동등을 위해 nginx 빌드시 echo 모듈을 추가한다.

# echo 모듈
git clone https://github.com/openresty/echo-nginx-module.git
export ECHO_PWD=$(pwd)/echo-nginx-module

# nginx configure 수행 및 빌드 및 설치
./configure --with-http_ssl_module --with-http_v2_module --with-http_stub_status_module --add-module=$ECHO_PWD
make
sudo make install


#####


# 이제 nginx.conf 를 다음과 같이 설정한다.
http {
... 생략 ...
    upstream ysoftman_web_server {
        server 127.0.0.1:55555;
        # bakcup : marks the server as a backup server. It will be passed requests when the primary servers are unavailable.
        server 127.0.0.1:55555 backup;
        server 127.0.0.1:55555 backup;
    }
    server {
... 생략 ...
        # /main 또는 /test 또는 /zzz 요청되는 경우
        location ~ ^/(main|test|zzz)$ {
            proxy_set_header Host $host;
            proxy_set_header Https-On $https;
            proxy_pass_request_headers  on;
            proxy_read_timeout     5s;
            proxy_connect_timeout  5s;
            # 업스트림서버의 응답이 에러(300 이상일 경우)인 경우 error_page 설정된 곳에서 처리
            proxy_intercept_errors on;
            # recursive_error_pages on;
            error_page 404 = /zzz_error_404;
            # 커넥션에러, 타임아웃, 502, 404 발생할때 backup 업스트림서버로 다시 요청
            proxy_next_upstream error timeout http_502 http_404;
            proxy_pass http://ysoftman_web_server/$1?$args;
            # echo_sleep 와 proxy_pass 는 각각의 핸들러를 가지고 있어
            # 둘을 같은 location 에 위치하면 충돌이 발생한다.
            # 왜냐면 nginx 는 location 에 하나의 핸들러만 허용하기 때문이다.
            # 업스트림은 처리되지 않고 3초 기다리고 클라이언트에 응답 준다.
            # echo_sleep 3;
        }
        location = /zzz_error_404 {
            echo_sleep 3;
            echo_location /retry_404;
        }
        location ~ ^/(retry_404)$ {
            proxy_pass http://ysoftman_web_server$request_uri;
            error_page 404 = /normal_error_404;
        }
        error_page  404              /normal_error_404;
        location = /normal_error_404 {

        }

... 생략 ...

}

# 우선 백엔드(업스트림서버)는 /zzz 가 404 응답을 주도록 설정되어 있다.
# 업스트림 404 응답시 sleep 후 재시도 흐름으로 진행된다.
1.클라이언트가 http://127.0.0.1:8080/zzz 로 요청
2. location ~ ^/(main|test|zzz)$ 에서 업스트림으로 요청, 이때 업스트이 404 에러를 주면 /zzz_error_404 로 핸들링하도록 설정해둔다.
3. 업스트림 404 에러 응답으로 /zzz_error_404 가 실행되고, echo_sleep 으로 3초 대기후 /retry_404 를 호출한다.
4. /retry_404 에서는 다시 업스트림 요청(proxy_pass)하게 되고, 이때 업스트림이 404 에러를 주면 끝낼 수 있도록 /normal_error_404 로 핸들링하도록 설정한다.
5. 다시 업스트림 404 에러를 받으면 /normal_error_404 에서 아무 처리하지 않고 클라이언트에게 404 응답을 준다.


#####


# 참고
# nginx 설치 및 위 내용 테스트 소스

# 백엔드 서버 소스

comments:

댓글 쓰기