MSA(API Gateway)

jhwan·2025년 2월 6일

MSA

목록 보기
3/3

Spring Cloud Gateway VS Load Balancing

Spring Cloud Gateway는 라우팅, 인증, 로깅, 필터링, 보안 기능을 한다. 그런데 LoadBalancing의 기능과 겹치는 부분이 있어 디테일한 차이가 무엇인지 GPT에게 물어보았다. GPT는 친절하게 다음과 같은 표를 보여주었다.

Spring Cloud Gateway는 공통 진입점에서 역할을 수행하고
로드 밸런싱은 동일한 서비스 인스턴스에 트래픽을 분산한다고 한다.
이렇게 말하니 차이가 명확히 와닿았다.

Spring Cloud Gateway와 필터

Spring Cloud Gateway가 필터가 하는 것과 다를 것이 없어서 GPT에게 Gateway를 사용하지 않고 모든 기능을 필터로 구현하면 안되냐고 물어봤다. 그러자 GPT는 필터만으로 Gateway의 기능을 구현할 때의 문제점을 알려주었다.

위 표를 통해 Spring Cloud Gateway가 많은 기능을 지원하기 때문에, 필터로 구현하는 것보다 편리하게 기능들을 구현할 수 있음을 알았다.

실습을 위한 dependency

Reactive Gateway, Spring Boot Actuator, Eureka Discovery Client, Lombok, Spring Web

실습 코드

후처리 코드

package com.spring_cloud.eureka.client.gateway;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.logging.Logger;

@Component
public class CustomPostFilter implements GlobalFilter, Ordered {

    private static final Logger logger = Logger.getLogger(CustomPreFilter.class.getName());


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            ServerHttpResponse response = exchange.getResponse();
            logger.info("Post Filter : Response status code is " + response.getStatusCode());
        }));
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

전처리 코드

package com.spring_cloud.eureka.client.gateway;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.logging.Logger;

@Component
public class CustomPreFilter implements GlobalFilter, Ordered {

    private static final Logger logger = Logger.getLogger(CustomPreFilter.class.getName());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        logger.info("Pre Filter: Request URI : " + request.getURI());

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

yml 파일

server:
  port: 19091  # 게이트웨이 서비스가 실행될 포트 번호

spring:
  main:
    web-application-type: reactive  # Spring 애플리케이션이 리액티브 웹 애플리케이션으로 설정됨
  application:
    name: gateway-service  # 애플리케이션 이름을 'gateway-service'로 설정
  cloud:
    gateway:
      routes:  # Spring Cloud Gateway의 라우팅 설정
        - id: order-service  # 라우트 식별자
          uri: lb://order-service  # 'order-service'라는 이름으로 로드 밸런싱된 서비스로 라우팅
          predicates:
            - Path=/order/**  # /order/** 경로로 들어오는 요청을 이 라우트로 처리
        - id: product-service  # 라우트 식별자
          uri: lb://product-service  # 'product-service'라는 이름으로 로드 밸런싱된 서비스로 라우팅
          predicates:
            - Path=/product/**  # /product/** 경로로 들어오는 요청을 이 라우트로 처리
      discovery:
        locator:
          enabled: true  # 서비스 디스커버리를 통해 동적으로 라우트를 생성하도록 설정

eureka:
  client:
    service-url:
      defaultZone: http://localhost:19090/eureka/  # Eureka 서버의 URL을 지정

GlobalFilter와 GatewayFilter의 차이점


GlobalFilter는 주로 로그 기록, 인증/인가, CORS, 공통 헤더 추가 등의 작업을 할 때 사용된다.

0개의 댓글