MSA (2) Spring Cloud Gateway - Filter

2025. 1. 7. 18:09·Infra

FIlter

 

Spring Cloud Gateway에서 Filter는 요청(Request) 및 응답(Response)을 처리하거나 변환하는 데 사용된다.

 

필터를 설정 이유

  1. 공통 로직 처리:
    • 모든 요청에 대해 동일한 작업(예: 인증, 로깅)을 중앙에서 처리가 가능하다.
  2. 유연한 요청 처리:
    • 서비스별로 맞춤형 필터를 적용해 요청을 동적으로 변환이 가능하다.
  3. 관리와 확장성:
    • 개별 서비스에 중복 코드를 작성할 필요 없이 Gateway에서 일괄 관리 가능하다.

.yml 필터 작성

server:
  port: 8000

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: api-gateway-service
  cloud:
    gateway:
      default-filters: # 모든 요청에 공통적으로 적용
        - name: AddRequestHeader
          args:
            name: Global-Header
            value: Global-Header-Value
        - name: AddResponseHeader
          args:
            name: Global-Response
            value: Global-Response-Value

      routes:
        # 사용자 서비스 그룹
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/**
          filters:
            - AddRequestHeader=User-Request, User-Request-Header
            - AddResponseHeader=User-Response, User-Response-Header

        # 주문 서비스 그룹
        - id: order-service
          uri: lb://ORDER-SERVICE
          predicates:
            - Path=/order-service/**
          filters:
            - name: RewritePath
              args:
                regexp: "/order-service/(?<segment>.*)"
                replacement: "/${segment}"
            - name: Hystrix
              args:
                name: orderFallback
                fallbackUri: forward:/fallback/order-service

        # 결제 서비스 그룹
        - id: payment-service
          uri: lb://PAYMENT-SERVICE
          predicates:
            - Path=/payment-service/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

 

코드 레벨 필터 구현

@Configuration
public class FilterConfig {

    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                // 사용자 서비스
                .route("user-service", r -> r.path("/user-service/**")
                        .filters(f -> f.addRequestHeader("User-Request", "User-Request-Header")
                                .addResponseHeader("User-Response", "User-Response-Header"))
                        .uri("lb://USER-SERVICE"))

                // 주문 서비스
                .route("order-service", r -> r.path("/order-service/**")
                        .filters(f -> f.rewritePath("/order-service/(?<segment>.*)", "/${segment}")
                                .hystrix(config -> config.setName("orderFallback")
                                        .setFallbackUri("forward:/fallback/order-service")))
                        .uri("lb://ORDER-SERVICE"))

                // 결제 서비스
                .route("payment-service", r -> r.path("/payment-service/**")
                        .filters(f -> f.requestRateLimiter(config -> config.setRateLimiter(redisRateLimiter())))
                        .uri("lb://PAYMENT-SERVICE"))
                .build();
    }

    // Redis 기반 Rate Limiter Bean 등록
    private RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20);
    }
}

 

Custom Filter 구현

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

    public CustomFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            // Pre Filter
            ServerHttpRequest request = exchange.getRequest();
            long startTime = System.currentTimeMillis();
            log.info("Custom Pre Filter: Request ID -> {}", request.getId());
            log.info("Custom Pre Filter: URI -> {}", request.getURI());

            // Add a custom request header
            ServerHttpRequest modifiedRequest = request.mutate()
                    .header("Custom-Request-Header", "CustomRequestValue")
                    .build();

            // Post Filter
            return chain.filter(exchange.mutate().request(modifiedRequest).build())
                    .then(Mono.fromRunnable(() -> {
                        ServerHttpResponse response = exchange.getResponse();
                        long processingTime = System.currentTimeMillis() - startTime;

                        log.info("Custom Post Filter: Response Status Code -> {}", response.getStatusCode());
                        log.info("Custom Post Filter: Processing Time -> {}ms", processingTime);

                        // Add a custom response header
                        response.getHeaders().add("Custom-Response-Header", "CustomResponseValue");
                    }));
        });
    }

    public static class Config {}
}
server:
  port: 8000

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: api-gateway-service
  cloud:
    gateway:
      routes:
        # 첫 번째 서비스
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
          filters:
            - CustomFilter

        # 두 번째 서비스
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**
          filters:
            - CustomFilter

      default-filters:
        - name: AddRequestHeader
          args:
            name: Global-Request
            value: GlobalRequestValue
        - name: AddResponseHeader
          args:
            name: Global-Response
            value: GlobalResponseValue

 

'Infra' 카테고리의 다른 글

MSA (1) - Spring Cloud Netflix Eureka  (0) 2025.01.02
'Infra' 카테고리의 다른 글
  • MSA (1) - Spring Cloud Netflix Eureka
JAVALA
JAVALA
워니‘s Diary
  • JAVALA
    정신줄 JAVA라
    JAVALA
  • 전체
    오늘
    어제
    • 분류 전체보기 (87)
      • Codding_Test (11)
        • BaekJoon (7)
        • Programmers (3)
      • Algorithm (11)
      • Daily (4)
        • memoir (4)
      • TroubleShooting (8)
        • InteliJ (1)
        • Server (1)
        • Infra (0)
        • DB (0)
      • Computer Science (1)
      • JAVA (8)
      • Javascript (0)
      • Spring Boot (7)
      • API (2)
      • Server (0)
      • DB (3)
        • ORACLE (1)
      • Infra (2)
      • Refactoring (1)
      • Plugin (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    springboot
    프로그래머스
    개발자
    자바 스프링부트
    프론트엔드 개발자
    개발자 부트캠프
    spring boot
    코딩테스트
    개발자 비전공자
    제로베이스
    자바 스프링
    자바 메소드
    자바 클래스
    자바 알고리즘
    개발자 국비
    자바
    스프링부트
    트리 자료구조
    백준
    백엔드 개발자
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
JAVALA
MSA (2) Spring Cloud Gateway - Filter
상단으로

티스토리툴바