본문 바로가기

트러블 슈팅

gateway에서의 FeignClient 사용

문제 정의

gateway는 기본적으로 reactive방식인 비동기 형식으로 진행되기 때문에 동기형식인 FeignClient를 사용하는데 몇가지 추가 설정이 필요합니다. gateway가 아닌 다른 서버에서 FeignClient사용을 할 때는 이런 설정들이 필요없긴 한데 말이죠.. 한번 설정들을 살펴보겠습니다.

 

해결 과정

build.gradle 파일을 따로 설명하지는 않겠습니다.

먼저 main class입니다. 당연히 feignclient 사용 설정을 해주어야겠죠?

 

@SpringBootApplication
@EnableFeignClients
public class GatewayApplication {

 

gateway에서는 FeignClient로 등록된 객체를 불러올 때 순환 참조 문제가 발생합니다. 저는 gateway에서 검증을 위해 auth서버로 요청을 보내야 하는데 보내기 위한 객체를 FeignClient로 등록을 해준 상태죠. 이때 App을 그냥 실행하게 되면 순환참조 문제가 발생하게 됩니다. (LocalJwtAuthenticationFilter에서 AuthService를, AuthService에서 LocalJwtAuthenticationFilter를 참조하게 됩니다)이를 해결하기 위해 Lazy loading을 사용해 문제를 해결해야합니다.

 

@Slf4j
@Component
public class LocalJwtAuthenticationFilter implements GlobalFilter {

    private final AuthService authService;

    public LocalJwtAuthenticationFilter(@Lazy AuthService authService) {
        this.authService = authService;
    }
    
    //... 로직

이런식으로 주입을 해줄 때 @Lazy를 명시해주어서 빈의 초기화를 지연시킬 수 있습니다. 즉, 실제로 빈이 필요할 때까지 초기화를 미루는 것입니다. 이로 인해 순환 참조 문제가 발생하지 않도록 할 수 있습니다.

 

다음으로 Lazy loading을 할 때 HttpMessageConverters 문제가 발생할 수 있습니다. 이를 따로 설정을 해주어야 하는데요,

// FeignClient 를 Lazy Load 할 경우 HttpMessageConverters 문제로 아래 config 설정이 필요
@Configuration
public class FeignConfig {
    @Bean
    public HttpMessageConverters messageConverters() {
        // 필요한 메시지 변환기를 설정
        return new HttpMessageConverters(new MappingJackson2HttpMessageConverter());
    }
}

위 코드처럼 HttpMessageConverters에 들어갈 객체를 직접 설정을 해 Bean으로 등록해주면 됩니다.

 

결과

gateway에서 순환참조가 일어나지 않고 auth 서버로 data가 가는 것을 postman을 통해 확인할 수 있었습니다.

 

깨달은 내용

비동기 형식 기반인 gateway에서 동기형식인 FeginClient 사용을 하려면 추가적인 작업이 꽤 필요하다는 걸 알게 되었습니다. 처음에는 gateway에서 기본 비동기로 동작하는데 비동기로 auth 서버에 보내면 안될까? 라고도 생각했는데 제가 gateway의 filter에서 설정한 내용은 토큰 검증을 위한 로직입니다. 이 부분이 비동기로 이루어지게 된다면 검증이 안된 상태로 다른 서버로 요청이 라우팅 되는 등의 문제가 발생할 수 있겠죠? 이 부분은 동기형식으로 진행되도록 설정하는 것이 맞는 것 같습니다. 

비동기는 아직 제대로 적용도 못해봤지만, 이런식으로 생각을 해서 무작정 비동기만 쓰지 말고 필요한 곳에 비동기와 동기형식을 적절히 배치해서 사용할 수 있도록 해야겠습니다!