Spring Cloud Gateway 👍🏻
- 스프링 기반 API Gateway
- 마이크로서비스 아키텍처에서 라우팅, 로드 밸런싱, 필터링 등 역할을 수행
- Spring 5, Project Reactor를 기반으로 구축되어 비동기 및 논블로킹 기능 지원
- Netty 서버를 사용하여 높은 성능을 제공
Gradle 의존성 추가
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
- API Gateway 서버를 Eureka Server(서비스 디스커버리)에 등록하기 위해 eureka-client 의존성 추가
Gateway Server 설정 파일 (application.yml)
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 GlobalFilter
preLogger : true
postLogger : true
routes:
- id : first-service
uri : lb://MY-FIRST-SERVICE
predicates:
- Path=/first-service/**
- Method=GET
filters:
- AddRequestHeader=first-request, first-request-header2
- AddResponseHeader=first-response, first-response-header2
- CustomFilter
- id : second-service
uri : lb://MY-SECOND-SERVICE
predicates:
- Path=/second-service/**
filters:
- RewritePath=/second-service/(?<segment>.*), /$\{segment}
- eureka.client
- register-with-eureka : 현재 애플리케이션을 Eureka Server에 등록하지에 대한 여부 (true)
- fetch-registry : Eureka Server로부터 인스턴스들의 정보를 주기적으로 가져올 것인지에 대한 속성 (true)
- service-url.defaultZone : Eureka Client가 Eureka Server에 연결하기 위한 URL 설정, defaultZone은 기본적으로 사용되는 Eureka Server의 URL를 나타낸다.
- spring.application.name
- MSA에서 해당 서비스를 구별할 수 있는 고유한 ID
- spring.cloud.gateway.default-filters : 전역 필터 설정 (모든 라우터 목록들에 대해서 해당 필터 적용)
- name : 전역 필터 클래스 이름
- args : 필터에 전달되는 추가 인수 설정
- spring.cloud.gateway.routes : 라우팅 규칙 목록 설정
- id : 라우팅 규칙 식별자 지정
- uri : 라우팅할 대상 서비스 지정
- lb://MY-FIRST-SERVICE
- Eureka에 등록된 서비스 이름 지정
- Spring Cloud Gateway에서는 Eureka에 등록된 서비스를 검색하고, Load Balancer는 Eureka에서 처리한다.
- lb://MY-FIRST-SERVICE
- predicates : 라우팅을 결정하기 위한 조건 설정
- Path=/first-service/** : 요청 경로가 "/first-service/**"와 일치하는 경우
- Method=GET : 요청 메서드가 GET일 경우
- filters : 라우팅에 적용할 필터 목록 설정
- AddRequestHeader=first-request, first-request-header2 : 요청 헤더 추가 필터 적용
- AddResponseHeader=first-response, first-response-headers : 응답 헤더 추가 필터 적용
- CustomFilter : 적용할 필터 클래스 이름 설정
- RewritePath=/second-service/(?<segment>.*), /$\{segment}
- :8000/second-service/posts로 gateway에 요청이 와서 second-service로 라우팅을 할 때, 실제 second-service에서는 :60000/second-service/posts로 대기해야 요청을 처리할 수 있다.
- @GET("/second-service/posts") 와 같이 - 하지만 second-service에서 모든 uri에 second-service를 포함시켜야 할까는 굳이 일까 싶다.
- 따라서 RewritePath를 통해 :8000/second-service/posts로 요청이 오더라도, second-service에서 uri에서 "second-service"를 빼고 :60000/posts로 요청을 처리할 수 있도록 Path를 재설정해주는 기능을 한다.
- :8000/second-service/posts로 gateway에 요청이 와서 second-service로 라우팅을 할 때, 실제 second-service에서는 :60000/second-service/posts로 대기해야 요청을 처리할 수 있다.
Gateway에 적용할 Filter 구현 (예시)
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter() {
super(Config.class);
}
@Data
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
@Override
public GatewayFilter apply(Config config) {
// Pre Filter
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter: request id -> {}", request.getId());
// Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("Custom POST filter: response code -> {}", response.getStatusCode());
}));
};
}
}
- Gateway Filter 를 구현하기 위해서는 AbstractGatewayFilterFactory를 상속해야 한다.
- 전역 필터와 지역 필터의 구현 방법은 동일하며, 설정 파일에 어디에 위치하느냐에 따라 전역 필터인지 지역 필터인지 결정된다.
- Tomcat이 아닌 Netty에서는 HttpRequestServlet과 HttpResponseServlet 대신 ServerHttpRequest와 ServerHttpResponse를 사용한다.
- spring.cloud.gateway.default-filters.args 로 설정한 인자는 Config 클래스를 만들어 넘겨 받을 수 있다.
- Pre Filter & Post Filter
- Pre Filter
- 요청이 라우팅 및 핸들러에 도달하기 전에 실행되는 필터
- 요청을 사전에 검증하고 변형하는 목적을 가진다. (요청의 인증, 인가, 헤더 수정, 요청 로깅 등의 작업)
- Post Filter
- 요청이 라우팅과 핸들러를 거친 후 응답을 처리하기 전에 실행되는 필터
- 응답을 사후에 변형하거나 로깅하는 것을 목적으로 한다. (응답의 헤더 수정, 응답 시간 측정, 응답 로깅 등의 작업)
- Mono.fromRunnable을 통해 Post Filter가 실행되기 전에 비동기 작업을 수행하고, 작업이 완료되면 Mono가 완료되어 Post Filter 단계로 진행한다.
- Pre Filter
MSA 공부
(1) Eureka Server 구성
(2) Eureka Client 구성
(3) Client Side Load Balancer & API Gateway 개념 정리
(4) Spring Cloud Gateway 구축
참고 강의 : https://www.inflearn.com/course/스프링-클라우드-마이크로서비스/dashboard
'개발 > Spring Cloud' 카테고리의 다른 글
[Spring Cloud] Config Server 설정 정보의 암호화 처리 (0) | 2023.06.20 |
---|---|
[Spring Cloud] Config Server 구축하기 (busrefresh 하기) (1) | 2023.06.19 |
[Spring Cloud] Client Side Load Balancer & API Gateway 개념 정리 (0) | 2023.06.11 |
[Spring Cloud] Eureka Client 구축하기 (0) | 2023.06.05 |
[Spring Cloud] Eureka Server 구축하기 (0) | 2023.06.05 |