출처: https://typemin.tistory.com/7 [TypeLOG:티스토리]

xx.xx.xxx/app/sign 으로 요청을 보내게 되었을 때 "redirect: login" 으로 리디렉션이 되어야 하는 것인데.

xx.xx.xxx/app/login(정상) 이 아닌 xx.xx.xxx/login(비정상) 이렇게 가는 것이 아닌가 ?
프록시를 한 백엔드 서버의 리디렉션의 요청을 nginx 설정에서 다시 바꿔주면 된다.

location ^~/app/ {
    proxy_redirect http://xx.xx.xxx/ http://xx.xx.xxx/app/;

    proxy_pass http://xx.xx.xxx:8089/;
}

 

반응형

나는 프로젝트를 열심히 하던 찰나 변수의 위치를 바꿔버리는 어이없는 실수를 하였다.

function void hello(int a, int b){}
// 실수 
hello(b,a);
// expect
hello(a,b);

빠르게 찾을 순 있었고 문제는 해결했다. 하지만 이로인해 내 코드를 의심 할 수 있는 좋은 기회였다.

 

위 문제가 아니었더라도 협업하는 환경에서 문제가 자잘하게 많았다.
동시 병렬적으로 작업을 하다보니 코드의 충돌이 생기고 서로 빠른 주기로 개발은 하는데 리뷰시간이 아깝다는 핑계로 리뷰를 안하더니 막상 코드의 히스토리를 이해하기위한 리뷰가 더 길어지는 문제는 말해 뭐해다.

 

내가 겪은 경험들이 말해주는 바는 "지금까지 일해왔던 방식은 일하는 시간이 증가하고 코드의 품질을 높이지는 못한다." 이다

도입 허락해줘 ..

코드 스타일도 다르고. 쪼개서 해야하는 리뷰도 안하니 다른 사람이 짠 코드의 히스토리를 이해하지 못한다.
내가 짠 코드도 못 믿는다. 남이 짠 코드는 더더욱 신뢰할 수 없다. 누가 검증을 해 줄수 있는가 ?

- 개발 시간의 증가, 코드 신뢰도 하락

검증은 하지만 자기 PC에서만 한다는 것, 막상 배포하려고 하니 환경 문제가 생긴다.

- 개발 외 업무 증가

신뢰 할 수 없는 개발 주기안에서 열심히 개발을 하고 나니 남는 건 버그와 연장 근무뿐이 아니겠는가? from su8y

 

CICD 도구를 통해 개발 상태, 배포 상태 등을 한 눈에 확인이 가능하므로 매니저한테도 좋은 일이 아닐수가 없다.

 

일하는 사람이라면 효율적으로 일 할수 있는 방법에 대해서 고민을 해봐야한다. 이를 위해서 깃랩 CI/CD 파이프라인 구상을 해보려고 한다.

지속적인 통합/제공/배포

  • ci: application 코드의 변경사항이 정기적으로 빌드 및 테스트(품질 검사 등)을 거쳐 공유 Repository에 병합이 되는 프로세스로 버그가 없고 좋은 application을 고객에게 전달하기 위한 초석입니다.
  • cd: 개발을 신명나게 하고나서 배포하는 과정의 자동화 프로세스입니다.

전체적인 CI/CD 흐름

  • 개발 후 배포 해야되는 브랜치로 Pull Requests(PR)을 보냅니다.
  • 해당 PR에 대해서 build, test, image push 를 합니다.
  • 실패했다면 사유와 알림을 알려줍니다.
  • 해당 파이프라인을 통해 발생한 개발 서버의 URL을 댓글, 이메일, SMS 등으로 안내해줍니다.

 

 

반응형

문제 상황

  • 특정 route의 GatewayFilter를 개별적으로 등록.
  • 보통의 상황에서는 문제가 생기지 않음.
  • 비동기 응답(Streaming Response, Mono, Flux 등)을 받을때는 사전 처리는 잘 되지만 사후 처리는 비동기 응답을 기다리지 않는 상황.

실행시키는 Proxied Service 비동기로 Streaming응답 형식을 하게되고 총 5초가 걸리게 했습니다.
(시간은 이해를 돕기위해 간소화)

0초 API 요청 
0초 GlobalFilter 사전 처리 동작 
0초 GatewayFilter 사전 처리 동작
0초 GatewayFilter 사후 처리 동작
5초 GlobalFilter 사후 처리 동작

즉, StreamResponse의 끝나는 시점에 GatewayFilter가 작동하면 되는 문제였습니다.

왜 그럴까 ?

GlobalFilter의 우선순위는 -1로 설정한 상황이었고.

스프링 공식문서 Combined Global Filter and GatewayFilter Ordering링크로 들어가보면 친절하게 우선순위를 GlobalFilter와 같이 사용하는 것이 있고 GatewayFilter도 똑같이 -1로 주어서 사용해봤더니 실패했습니다.

@Component
public class UserReqeustThrottlingFilter implements GatewayFilter, Ordered {
    private static final String REDIS_UNIQUE_USER = "unique_user::";

    @Autowired
    RedisTemplate<String, Integer> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       // ...
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

스프링의 공식문서 내용 중 WebHandlerfilterChain을 통해서 요청이 실행된다고 합니다.

Gateway WebHandler의 구현체 FilteringWebHandler

FilteringWebHandler는 내부의 GatewayFilterAdapter를 통해서 실행이 됩니다. 우선순위를 잘 찾아보면

제가 등록한 UserRequestThrottlingFilter가 우선순위가 정상적으로 된 걸 보았는데NettyWriteResponseFilter 보다는 낮을 걸 확인 할 수 있습니다.

NettyWriteResponseFilter클래스가 비동기 응답을 처리하는 필터였고 해당 필터보다 위쪽에 있어야지 제가 원하는 응답을 얻을 수 있습니다.

해결

이제야 문제는 해결됩니다. 이유를 몰랐던 우선순위에 따른 응답이 달라지는 것은 NettyWriteResponseFilter와의 우선순위 문제였고 커스텀한 글로벌 필터는 항상 NettyWriteReponseFilter보다 위 입니다.

하지만 GatewayFilter는 아니었던 거죠 우선순위를 NettyWriteResponseFilterorder값인 -1로 주는 것이 아닌 확실하게 -2를 주면서 문제는 해결됩니다.

index 2 에 위치하게 됩니다.

ㅜㅜ

새로운 Spring Project인 Cloud Gateway에 대해서 알게된지 3일차지만 많은 공부가 되었습니다.
이 문제 해결법이 도움이 됐으면 좋겠네요.

반응형

'Programming > Spring' 카테고리의 다른 글

Spring MVC(2). 프론트컨트롤러(DispatcherServlet)  (0) 2023.04.19
Spring MVC(1). 서블릿  (0) 2023.04.19

두 개의 LinkedList L1, L2를 통한 덧셈을 구현하면 됩니다.
이 부분은 자료구조 LinkedList를 잘 사용하면 되는데요.
L1 과 L2 를 가르키는 포인터를 순차적으로 같이 움직이면서 덧셈을 구현해나가면 됩니다.

덧셈에서 중요한 부분인 $9 + 9$ 를 하였을때 1의 자리수에서 10의 자리수로 1을 올려주는 것을 잘 해결해나가면 되는데요.

올림수를 별도로 따로 처리한다기보다는 앞으로 이어질 Node에 미리 값 1을 세팅을 해주는 것으로 해결하였습니다.

반응형

+ Recent posts