Backend/Spring Cloud

Spring Cloud Gateway Filter

야뤼송 2022. 4. 19. 13:05
반응형
해당 내용은 인프런 이도원님의 "Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)"를 듣고 정리한 내용입니다.

 

1. Spring Cloud Gateway Filter란?

  • Http 요청, 응답에 대한 내용을 추가/수정 할 수 있도록  한다.
  • 요청 전 처리하는 필터를 Pre Filter, 요청 후 처리하는 필터를 Post Filter라고 한다.

2. Spring Cloud Gateway Filter의 동작 순서

  1. GateWay Handler를 통해 사용자 요청에 대한 내용을 받게된다.
  2. Predicate: 사용자 요청에 대해서 Spring Cloud Gateway에 설정된 조건을 찾아 Filter를 거쳐 서비스로 route되도록 한다.
  3. Pre Filter :Http 요청에 대해 과정을 수행한다.
  4. Post Filter : Http 응답에 대해 과정을 수행한다.

3. Spring Cloud Gateway Filter 구현하기

    • AbstractGatewayFilterFactory를 상속받는 Filter 클래스 생성한다.
      AbstractGatewayFilterFactory에는 자기 자신의 내부클래스를 매개변수로 등록한다.
      public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
      
          @Data
          public static class Config {
              // Put the configuration information
              private String baseMessage;
              private boolean preLogger;
              private boolean postLogger;
      
          }
       }
    • Filter의 기능을 구현하기 위해 AbstractGatewayFilterFactory에서 apply 메소드를 오버라이딩하여 준다.
          @Override
          public GatewayFilter apply(Config config) {
              return null;
          }
    • Pre Filter와 Post Filter 기능을 위해서는 apply 메소드안에 내용을 구현한다.
      • Pre Filter :  "(exchage, chgain) -> " 구문 다음에 Pre Filter에서 처리할 내용을 작성한다.
      • Post Filter : "chain.filter(exchange).then(Mono.fromRunnable(() -> " 구분 이후에 Post Filter의 내용을 작성한다.
      @Override
      public GatewayFilter apply(Config config) {
      
          // Global Filter
          return (exchange, chain) -> {
      
              ServerHttpRequest request = exchange.getRequest();
              ServerHttpResponse response = exchange.getResponse();
      
              log.info("Global Filter baseMessage : {}", config.getBaseMessage());
      
              if (config.isPreLogger()) {
                  log.info("Global Filter Start: request id -> {}", request.getId());
              }
              //Global Post Filter
              return chain.filter(exchange).then(Mono.fromRunnable(() -> {
      
                  if (config.isPostLogger()) {
                      log.info("Global Filter : response code -> {}", response.getStatusCode());
                  }
              }));
          };
      }

 

4. Global Filter의 적용과 Custom Filter의 적용

  • Spring Cloud Gateway의 경우 Global Filter와 서비스 별로 개별 적용을 위한 Custom  Filter 를 각각 적용할 수 있다.
  • 적용 방법은 yml 파일 내에 설정 값을 적용해준다.
  • Global Filter
    • spring.cloud.gateway.default-filters에 설정한다.
    • name : 3번 단계에서 구현한 Filter 클래스 이름을 입력한다.
    • args : Filter Class 내부 Config에 작성한 변수에 대한 config 내용을 설정한다.
                (Config에 별도로 변수를  사용하지 않은 경우 생략 가능하다)
  • Custom Filter
    • spring.cloud.gateway.routes에 설정한다.
    • filters.name : 구현한 Custom Filter 클래스 이름을 입력한다.
    • args : Filter Class 내부 Config에 작성한 변수에 대한 config 내용을 설정한다.
                (Config에 별도로 변수를  사용하지 않은 경우 생략 가능하다)
    spring:
      cloud:
        gateway:
          #Global Filter 적용
          default-filters:
            - name: GlobalFilter
              args:
                baseMessage: Spring Cloud Gateway GlobalFilter
                preLogger: true
                postLogger: true
          routes:
            - id: second-service
              uri: lb://MY-SECOND-SERVICE
              predicates:
                - Path=/second-service/**
              #Custom Filter 적용
              filters:
                - name: CustomFilter
                  args:
                    baseMessage: Spring Cloud Gateway CustomFilter
                    preLogger: true
                    postLogger: true

 

 

5. Filter별 동작 순서

  • Global Filter는 Custom Filter 보다 먼저 실행이 된다.
  • Cusom Filter들의 경우 OrderedGatewayFilter 를 통해 순서를 제어할 수 있다.
    • 구현방법은 apply()에서 new OrderedGatewayFilter를 선언하여 우선순위를 설정하여 준다.
          @Override
          public GatewayFilter apply(Config config) {
      
              // Logging Filter
              GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
                  
                  //pre-fitler & post-fitler 작성
              }, OrderedGatewayFilter.LOWEST_PRECEDENCE);
      
              return filter;
          }
    • 우선 순위를 지정하는 방법에는 다른 필터보다 먼저 우선 순위를 가지게 하는 "HIGHEST_PRECEDENCE",  우선 순위를 가장 낮게하는 "LOWEST_PRECEDENCE" 설정이 존재한다.
    • 만약 Log를 남기는 Custom Filter를 생성하고, 필터의 우선위를 LOWEST_PRECEDENCE 설정한 경우 가장 마지막에 실행하게 된다.
    • 우선 순위가 지정되지 않은 Filter의 경우 yml에 설정된 순으로  Filter가 실행된다.

 

반응형