Spring Cloud GateWay

Manx·2024년 1월 28일
0

MSA

목록 보기
1/1

MSA 강의를 들으며, Zuul을 이용해 API Gate Way를 구성하는 영상을 보았는데, Zuul은 더이상 서비스가 되지 않아 Spring Cloud GateWay(SCG)를 사용해보며 간단하게 정리하고자 한다.

1. Gate Way란

가장 대표적인 역할은 API Routing이다.
특정 URL로 요청이 들어오면, MSA로 구축해 놓은 서비스에 알맞는 서버로 라우팅해 주는 역할을 한다.

출처 : 오늘의 집 블로그

그 외의 API Gateway의 역할

  • 인증 (Authentication) & 인가 (Authorization)
  • 로깅 (Logging) & 모니터링 (Monitoring)
  • 입력 유효성 검사

단점

  • 모든 API가 GateWay를 통과하므로 SPOF가 된다.
  • 응답 시간이 지연될 수 있다.

모든 요청이 한 곳에서 처리되기 때문에, 공통으로 처리할 수 있는 작업들을 해당 GateWay에서 진행할 수 있다.
각 마이크로 서비스들은 인증, 인가 등의 작업을 신경쓰지 않고, 비즈니스 로직에만 집중할 수 있다.


-> 클라이언트 단에서 서비스로 바로 요청하는 Ribbon과 같은 서비스가 있었지만, 단일진입점을 만들어 인증, 인가 / 로깅과 같은 공통된 로직을 수행할 수 있는 장점으로 Gateway를 사용하게 되었다. ( Ribbon은 spring boot 2.4에서 Maintenance 되었음)

왼쪽 : Client에서 바로 마이크로서비스로 요청
오른쪽 : API Gatewayfmf 통해 각 마이크로서비스로 요청

출처 : 마이크로소프트-.NET 마이크로 서비스 - 아키텍처

2. spring cloud Gate Way

Spring Cloud Gate Way에 대해 알아보자.

  • Spring에서 제공하는 오픈 소스 기반의 Gateway 서비스
  • Netty 기반의 비동기(Asynchronous) 요청 처리 제공

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와는 다른데,차이는 다음과 같다.

  1. starter-gateway-mvc
  • Spring MVC를 기반으로 한다.
  • 서블릿 API에 기반한 동기 블로킹 I/O 모델을 사용한다. ( Tomcat )
  1. startet-gateway
  • Spring WebFlux를 기반으로 한다.
  • 비동기 논블로킹 I/O를 지원한다. ( Netty )
  • 높은 처리량과 확장성을 제공한다.

MSA를 구축할 때, Gateway는 비동기 통신이 권장된다.
왜 그럴까?

  • 동기 호출 : 각 MS의 응답이 올 때 까지 Thread는 기다려야 한다.
    • 응답을 기다리는 데 스레드를 모두 소진해서, 추가 요청을 처리할 수 없게 될 수 있다.
  • 스레드가 서버로 요청하고 난 뒤, 응답을 기다리는 것이 아닌 다른 일을 처리하다 응답이 왔을 때 해당 작업을 수행하면, 불필요하게 리소스를 점유하는 일을 예방할 수 있다.

-> 이벤트 루프를 이용한 비동기 프로그래밍 ( 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 작업을 할 때 함께 다루도록 하겠다.


참고 자료

profile
백엔드 개발자

0개의 댓글