레이블이 echo인 게시물을 표시합니다. 모든 게시물 표시
레이블이 echo인 게시물을 표시합니다. 모든 게시물 표시

echo reverse proxy ingress localhost 404 error

/*
echo golang web framework 의 proxy 사용시 upstream 을 ingress domain 을 사용하면 404 not found 응답 이슈가 발생했다.

echo proxy 사용 예시 참고
https://echo.labstack.com/cookbook/reverse-proxy/

같은 localhost 로 업스트림 설정하면 문제가 없다.
http://localhost:8080 -> http://localhost:8081 (upstream local)

ingress domain 으로 업스트림을 설정하면 404 응답을 받는다.
http://localhost:8080 -> http://ysoftman.dev:8081 (upstream ingress)
404 Not Found

nginx pod 에 로그를 보면 다음과 같은 메시지가 기록된다.
호스트가 ysoftman.dev 로 되어야 할것 같은데, localhost 로 파악돼 pod 까지 요청이 전달되지 않는다.
Skipping metric for host not being served" host="localhost"

해결 방법
프록시 설정전 다음과 같이 핸들러를 등록하고 request host 를 ysoftman.dev 로 설정하면 ysoftman.dev 로 부터 200 OK 응답을 받는다.
*/

package main

import (
"net/http"
"net/url"

// ModifyResponse 사용을 위해선 echo v4 가 필요
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)

func main() {
url, _ := url.Parse("http://ysoftman.dev:8081")
e := echo.New()
g := e.Group("/test")

// 프록시 설정 전 request host 를 upstream host 로 변경
g.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Request().Host = url.Host
return next(c)
}
})

// set proxy upstream
proxyTargets := []*middleware.ProxyTarget{
{
URL: url,
},
}
g.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{
Balancer: middleware.NewRoundRobinBalancer(proxyTargets),
ModifyResponse: func(resp *http.Response) error {
return nil
},
}))
}

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 설치 및 위 내용 테스트 소스

# 백엔드 서버 소스