본문 바로가기
프로젝트/FitTrip

[트러블슈팅] OpenFeign과 Spring Cloud Gateway간의 순환 참조 오류

by 진꿈청 2024. 6. 25.

🐞 버그 설명

OpenFeign과 Spring Cloud Gateway를 함께 사용했을 때 Bean 순환 참조가 오류가 발생했습니다.

 

로그를 보니 FeignClient와 Gateway Router 부분에서 해당 문제가 발생한 것 같습니다.(로그 참고)

처음엔 그냥 의존성 주입 코드에 문제가 있는 줄 알았으나 코드상의 문제는 없었습니다.

 

Gateway가 아닌 일반 서비스에서는 OpenFeign 사용에 문제가 없었으며 관련 설정에도 문제가 없었습니다.

또한, OpenFeign과 설정에서 같은 user-service 키워드를 사용하기에 해당 부분을 수정하였음에도 해결되지 않았습니다.

 

 

AuthFeignClient 인터페이스

@FeignClient(name = "auth-service")
@Qualifier("AuthFeignClient")
public interface AuthFeignClient extends AuthClient{

    @Override
    @PostMapping("/isLogin")
    boolean isValidToken(String accessToken);
}

 

applicaiton.yml

      routes:
        - id: user-service
          uri: lb://USER-SERVICE # 포워딩할 주소, http://localhost:8000/user 로 들어오면 http://localhost:64412 로 포워딩
          predicates:
            - Path=/api/user/** # 해당 gateway 서버의 /user/**로 들어오는 요은 user-service로 인식하겠다는 조건
          filters:
            - RewritePath=/api/user/?(?<segment>.*), /$\{segment}

 

따라서, 제가 내린 결론은 OpenFeign의 로드밸런서와 Gateway의 라우터 필터간의 Bean 중에 순환 참조되는 부분에 있는 것 같습니다.

그래서, @Lazy를 추가하여 런타임시 필요할 때 빈을 등록하는 것으로 수정하였습니다.

 

 

AuthorizationFilter

@Slf4j
@Component
public class AuthorizationFilter extends AbstractGatewayFilterFactory<AuthorizationFilter.Config> {

    private final JwtTokenProvider jwtTokenProvider;

    private final AuthClient authClient;

    public AuthorizationFilter(JwtTokenProvider jwtTokenProvider, @Lazy @Qualifier("AuthFeignClient") AuthClient authClient){
        super(Config.class);
        this.jwtTokenProvider = jwtTokenProvider;
        this.authClient = authClient;
    }
 ....
}

위 설정 후 실행했을 때 순환 참조 문제는 발생하지 않았으나, 이게 실제 런타임시에도 잘 동작할지는 모르겠습니다.


그리하여 좀 더 관련 정보를 찾던 중 아래 글을 발견하긴 하였고 똑같이 @Lazy를 사용하였습니다.

(하지만, Spring에서 순환 참조는 아예 발생하지 않도록 하는 것이 원칙이기에 이게 명확한 해결법인지 모르겠습니다.)

https://stackoverflow.com/questions/75096788/feign-client-with-spring-cloud-gatewayfilter-cause-cycle-dependency

 

Feign Client with Spring Cloud GatewayFilter cause cycle dependency

During certain checks, I need to make a request to my Microservice in the Gateway Filter. When I define the Feign class in the GatewayFilter(my SecurityFilter.java) class, it gives the following er...

stackoverflow.com

 

관련하여 정보가 있으시거나 @Lazy를 사용하여본 경험이 있으신분은 코멘트 부탁드리겠습니다.

✅ 예상 결과

순환 참조 문제 해결 예상

❗ 실제 결과

image

💻 버그 시뮬레이션

  1. 의존성 주입 코드 확인
  2. 의존성 주입 패턴 변경
  3. application.yml 또는 OpenFeignClient 수정
  4. @Lazy 어노테이션 삽입

 

📄 로그

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  authorizationFilter defined in file [/Users/hanyoonsoo/hobbytrip/hobbytrip/src/backend/gateway-service/build/classes/java/main/capstone/gatewayservice/global/filter/AuthorizationFilter.class]
↑     ↓
|  capstone.gatewayservice.global.external.AuthFeignClient
↑     ↓
|  corsGatewayFilterApplicationListener defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]
↑     ↓
|  routePredicateHandlerMapping defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]
↑     ↓
|  cachedCompositeRouteLocator defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]
↑     ↓
|  routeDefinitionRouteLocator defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]
└─────┘

🌏 환경

No response

🙋🏻 More

No response