의존성
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}
API 게이트웨이
클라이언트의 요청을 받아 백엔드 서비스로 라우팅하고, 다양한 부가 기능을 제공하는 중간 서버이다.
클라이언트와 서비스 간의 단일 진입점 역할을 하며, 보안, 로깅, 모니터링, 요청 필터링 등을 처리한다.
API 게이트웨이 주요 기능
라우팅 : 클라이언트 요청을 적절한 서비스로 전달
인증 및 권한 부여 : 요청의 인증 및 권한을 검증
로드 밸런싱 : 여러 서비스 인스턴스 간의 부하 분산
모니터링 및 로깅 : 요청 및 응답을 로깅하고 모니터링
요청 및 응답 변환 : 요청과 응답을 변환하거나 필터링
Spring Cloud GateWay
Spring 프로젝트의 일환으로 개발된 API 게이트웨이로, 클라이언트 요청을 적절한 서비스로 라우팅하고 다양한 필터링 기능을 제공한다.
Spring Cloud GateWay 주요 특징
동적 라우팅 : 요청의 URL 패턴에 따라 동적으로 라우팅
필터링 : 요청 전후에 다양한 작업을 수행할 수 있는 필터 체인 제공
모니터링 : 요청 로그 및 메트릭을 통해 서비스 상태 모니터링
보안 : 요청의 인증 및 권한 검증
코드
spring:
main:
web-application-type: reactive # Spring 애플리케이션이 리액티브 웹 애플리케이션으로 설정됨
application:
name: gateway-service # 애플리케이션 이름을 'gateway-service'로 설정
cloud:
gateway:
server:
webflux:
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 # 서비스 디스커버리를 통해 동적으로 라우트를 생성하도록 설정
버전에 따라 routes가 webflux 안에 들어가도록 변경이 되었다.
Filter
Global Filter : 모든 요청에 대해 작동하는 필터
Gateway Filter : 특정 라우트에만 적용되는 필터
필터를 구현하려면 GlobalFilter 또는 GatewayFilter 인터페이스를 구현하고 ,filter 메서드를 오버라이드 해야한다.
Filter 주요 객체
Mono : Mono는 리액티브 프로그래밍에서 0또는 1개의 데이터를 비동기적으로 처리한다.
Mono<Void> 는 아무 데이터도 반환하지 않음을 의미한다.
ServerWebExchange : Http요청과 응답을 캡슐화한 객체이다.
exchange.getRequest() : Http 요청을 가져온다.
exchange.getResponse() : Http 응답을 가져온다.
GatewayFilterChain : 여러 필터를 체인처럼 연결한다.
chain.filter(exchange) : 다음 필터로 요청을 전달한다.
Filter 시점별 종류
Pre :
요청이 처리되기 전에 실행된다. 따라서 Pre필터에서는 요청을 가로채고 필요한 작업을 수행한 다음, 체인의 다음 필터로 요청을 전달한다. 이때 추가적인 비동기 작업을 수행할 필요가 없기 때문에 then 메서드를 사용할 필요가 없다.
@Component
@RequiredArgsConstructor
public class CustomPreFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(CustomPreFilter.class.getName());
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
log.info("Pre Filter : Request URI : " + request.getURI());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
Post :
요청이 처리된 후, 응답이 반환되기 전에 실행된다. Post필터에서는 체인의 다음 필터가 완료된 후에 실행되어야 하는 추가적인 작업을 수행해야 한다. 따라서 chain.filter(exchange) 를 호출하여 다음 필터를 실행한 후, then 메서드를 사용하여 응답이 완료된 후에 실행할 작업을 정의한다.
@Component
@RequiredArgsConstructor
public class CustomPostFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(CustomPostFilter.class.getName());
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
log.info("Post Filter : Response status code is " + response.getStatusCode());
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
'BACKEND & SERVER > Spring Boot MSA' 카테고리의 다른 글
| [Spring Boot] JitPack | MSA 프로젝트에서 공통 관심사 분리하기 (0) | 2025.11.03 |
|---|---|
| [Spring Boot] DTO에 Serializable을 사용하는 이유 (0) | 2025.10.30 |
| [Spring Boot] Resilience4j | 서킷브레이커 (0) | 2025.10.27 |
| [Spring Boot] RestClient vs FeignClient (0) | 2025.10.24 |
| [Spring Boot] FeignClient & 로드밸런싱 (0) | 2025.10.24 |
