ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Cloud 2일차] API Gateway 필터 순서 및 Eureka Load Balancing
    Spring/Cloud 2024. 9. 11. 14:21
    728x90
    반응형

    Spring Cloud Gateway에서 API Gateway 필터 구성하기

    사용자 정의 필터를 생성하려면 AbstractGatewayFilterFactory를 상속 받은 후 apply 메서드를 구현한다.

    GatewayFilter를 반환해야 하며 GatewayFilter를 구현한 OrderedGatewayFilter로 생성하면 실행 순서를 지정할 수 있다.

    OrderedGatewayFilter는 Ordered도 구현하고 있는데 Ordered 객체 안에는 HIGHEST_PRECEDENCE (Integer.MIN_VALUE)와 LOWEST_PRECEDENCE(Integer.MAX_VALUE)가 있어서 가장 먼저 실행되야 하는것과 가장 마지막에 실행되어야 한는 필터의 순서를 쉽게 지정해줄 수 있다.

    추가 ) Filter의 우선 순위는 낮을수록 먼저 실행되나.

    @Component
    @Slf4j
    public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {
    
      public LoggingFilter() {
        super(Config.class);
      }
    
      @Override
      public GatewayFilter apply(Config config) {
        return new OrderedGatewayFilter((exchange, chain) -> {
          ServerHttpRequest request = exchange.getRequest();
          ServerHttpResponse response = exchange.getResponse();
    
          log.info("Logging Filter baseMessage : {}", config.getBaseMessage());
    
          if(config.isPreLogger()) {
            log.info("Logging PRE Filter Start : request id = {}", request.getId());
          }
    
          return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            if(config.isPostLogger()){
              log.info("Logging Filter End : response code = {}", response.getStatusCode());
            }
          }));
        }, OrderedGatewayFilter.LOWEST_PRECEDENCE); // 가장 낮은 순서를 갖는다. (Integer.MAX_VALUE)
      }
    
      @Data
      public static class Config {
       private String baseMessage;
       private boolean preLogger;
       private boolean postLogger;
     }
    }

    하나의 Route에 여러개의 필터 적용

    application.yml에서 여러 Filter를 Route에 적용할 수 있는데 Filter에 우선 순위를 별도로 지정하지 않은 경우 나열된 순서대로 적용된다.

    spring:
      application:
        name: apigateway-service
      cloud:
        gateway:
          default-filters:
            - name: globalFilter
              args:
                baseMessage: Global Filter
                preLogger: true
                postLogger: true
        routes:
          - id: first-service
            uri: http://localhost:8081
            predicates:
              - Path=/first-service/**
            filters:
              - CustomFilter
              - NoArgsFilter
          - id: second-service
            uri: http://localhost:8082
            predicates:
              - Path=/second-service/**
            filters:
              - name: CustomFilter
              - name: LoggingFilter
                args:
                  baseMessage: Logging Filter
                  preLogger: true
                  postLogger: true

    만약 Filter가 인자( AbstractGatewayFilterFactory 제네릭 타입 파라미터 객체 )를 초기화 하고 싶다면 해당 Route의 모든 Filter앞에 - name:을 붙여줘야 하며 그렇지 않은 상황에서는 name:은 생략이 가능하다.

    Eureka와 통합하여 서비스 사용

    동작 순서

    Client -> API Gateway(실제 서비스 URL X) -> Eureka(해당 서비스 URL search) -> API Gateway(실제 서비스 URL O) -> MicroService -> API Gateway -> Clinet

    server:
      port: 8000
    
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:8761/eureka
    
    spring:
      application:
        name: apigateway-service
      cloud:
        gateway:
          default-filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud GateWay Global Filter
                preLogger: true
                postLogger: true
          routes:
            - id: first-service
              uri: lb://MY-FIRST-SERVICE
              predicates:
                - Path=/first-service/**
              filters:
                - CustomFilter
            - id: second-service
              uri: lb://MY-SECOND-SERVICE
              predicates:
                - Path=/second-service/**
              filters:
                - name: CustomFilter
                - name: LoggingFilter
                  args:
                    baseMessage: Hi, threr.
                    preLogger: true
                    postLogger: true
    • 각 Route의 uri는 lb://로 시작하며 뒤에는 Eureka에 등록된 서비스 이름을 작성
      • 등록된 서비스 이름은 실제 서비스의 application.name을 대문자로 치환한 것이다.
    • Eureka는 자동으로 서비스 인스턴스 간에 라운드 로빈 방식으로 로드 밸런싱 처리
    728x90
    반응형
Designed by Tistory.