문제 상황
- 특정 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;
}
}
스프링의 공식문서 내용 중 WebHandler
가 filterChain
을 통해서 요청이 실행된다고 합니다.
Gateway WebHandler의 구현체 FilteringWebHandler
FilteringWebHandler
는 내부의 GatewayFilterAdapter
를 통해서 실행이 됩니다. 우선순위를 잘 찾아보면
제가 등록한 UserRequestThrottlingFilter
가 우선순위가 정상적으로 된 걸 보았는데NettyWriteResponseFilter
보다는 낮을 걸 확인 할 수 있습니다.
NettyWriteResponseFilter
클래스가 비동기 응답을 처리하는 필터였고 해당 필터보다 위쪽에 있어야지 제가 원하는 응답을 얻을 수 있습니다.
해결
이제야 문제는 해결됩니다. 이유를 몰랐던 우선순위에 따른 응답이 달라지는 것은 NettyWriteResponseFilter
와의 우선순위 문제였고 커스텀한 글로벌 필터는 항상 NettyWriteReponseFilter
보다 위 입니다.
하지만 GatewayFilter
는 아니었던 거죠 우선순위를 NettyWriteResponseFilter
의 order
값인 -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 |