MSA 강의를 들으며, Zuul을 이용해 API Gate Way를 구성하는 영상을 보았는데, Zuul은 더이상 서비스가 되지 않아 Spring Cloud GateWay(SCG)를 사용해보며 간단하게 정리하고자 한다.
가장 대표적인 역할은 API Routing이다.
특정 URL로 요청이 들어오면, MSA로 구축해 놓은 서비스에 알맞는 서버로 라우팅해 주는 역할을 한다.
출처 : 오늘의 집 블로그
그 외의 API Gateway의 역할
단점
모든 요청이 한 곳에서 처리되기 때문에, 공통으로 처리할 수 있는 작업들을 해당 GateWay에서 진행할 수 있다.
각 마이크로 서비스들은 인증, 인가 등의 작업을 신경쓰지 않고, 비즈니스 로직에만 집중할 수 있다.
-> 클라이언트 단에서 서비스로 바로 요청하는 Ribbon과 같은 서비스가 있었지만, 단일진입점을 만들어 인증, 인가 / 로깅과 같은 공통된 로직을 수행할 수 있는 장점으로 Gateway를 사용하게 되었다. ( Ribbon은 spring boot 2.4에서 Maintenance 되었음)
왼쪽 : Client에서 바로 마이크로서비스로 요청
오른쪽 : API Gatewayfmf 통해 각 마이크로서비스로 요청
출처 : 마이크로소프트-.NET 마이크로 서비스 - 아키텍처
Spring Cloud Gate Way에 대해 알아보자.
Gateway Hanlder Mapping, Gateway Web Handler를 통해, Route 경로에 포함되는지 확인 후, 지정되어 있는 Filter로 보내 Request를 Filtering한다.
출처 : https://cloud.spring.io/spring-cloud-gateway/reference/html/
Spring Initailizer를 통해 spring-cloude-gateway를 추가하면, 자동적으로
spring-cloud-starter-gateway-mvc가 의존성에 추가된다.
이는 spring-cloud-starter-gateway와는 다른데,차이는 다음과 같다.
MSA를 구축할 때, Gateway는 비동기 통신이 권장된다.
왜 그럴까?
-> 이벤트 루프를 이용한 비동기 프로그래밍 ( Spring WebFlux )
그래서 Netty를 사용하는 것 !
그렇다면, gateway가 비동기로 동작하면 모든 마이크로 서비스는 비동기여야 할까?
-> 그럴 필요 없다.
Gateway는 서비스들 사이의 통신을 중계하는 역할이지, 각 서비스들은 MVC, WebFlux 또는 다른 웹 프레임워크를 사용하여 개발될 수 있다.
다음은 간략한 코드 예시이다.
first-service, second-service를 띄워놓았고, 각 요청별로 8001, 8002 port로 라우팅 되도록 설정했다.
first-service/welcome이 요청되었을 때, first-service는 제거하고, 127.0.0.1:8001/welcome으로 요청되도록 filtering을 추가하였다.
@SpringBootApplication
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/first-service/**")
.filters(f -> f.rewritePath("/first-service/(?<segment>.*)", "/${segment}"))
.uri("http://127.0.0.1:8001"))
.route(r -> r.path("/second-service/**")
.filters(f -> f.rewritePath("/second-service/(?<segment>.*)", "/${segment}"))
.uri("http://127.0.0.1:8002"))
.build();
}
}
추가적인 Filtering으로 Global, Custom 등 다양하게 설정이 가능한데, 나중에 직접 서비스를 구현해 보면서 JWT, Logging 작업을 할 때 함께 다루도록 하겠다.