API Gateway, MSA의 출입구 ( Spring Cloud Gateway )

BlackHan·2023년 12월 8일
3

저번 시간에 Spring Cloud를 알아보았다. 이번엔 Spring Cloud Gateway에 대해서 좀 더 자세하게 알아보자


Spring Cloud Gateway란?

Spring을 기반으로 API를 구축하는 데 사용되는 Gateway이며
클라이언트와 서비스 사이에 통신을 관리하는 역할을 한다.

API Gateway 구성에는 Spring Cloud Gateway를 활용되며, 이는 API 라우팅, 필터링, 로드 밸런싱과 같은 역할을 효과적으로 수행한다는 것을 학습한 바 있다.

라우팅 (Routing) : 데이터가 이동할 때 이동 경로를 정하는 프로세스
로드 밸런싱 (Load Balancing) : 여러 서버에게 들어오는 트래픽을 균등하게 분배하여 부하를 분산시키는 기술
필터 (Filter) : Pre-filter, Post-filter, 라우팅 필터, 에러 필터가 있으며 이들은 요청을 받아 보안이나 헤더 추가와 같은 특정 작업을 수행한다.

왜 사용하는가?

장점

  • 오픈소스 기반으로 라이선스 투자 비용이 없다.
  • Spring에서 제공하는 Boot, Security, OAuth2 등 다양한 컴포넌트와 조합하여 효율적인 개발이 가능하다.
  • WebFlux 기반의 Non-Blocking을 사용한다. 이는 I/O 작업이 완료되기를 기다리지 않고 다른 작업을 수행할 수 있으며 빠른 응답을 확보할 수 있음을 의미한다.
  • yaml 파일로 간단하게 라우팅이 가능하다.

단점

  • 다른 API 게이트웨이에 비해 기능들이 미숙하다. 특정한 UI 기반의 관리 도구가 필요한 경우, 추가적인 구성을 활용하여 이를 보완해야 한다.
  • 모든 요청은 추가적인 오버헤드를 갖게 되어 간단한 요청에 있어서는 비효율적일 수 있다.

동작 과정

1. Client의 HTTP 요청이 Gateway로 들어온다.
2. Gateway Handler Mapping에서 라우팅 기능을 사용하여 이 요청을 어떤 라우트로 보낼지 결정한다.
3. 해당 라우트에 대응하는 WebHandler가 실행된다. 이는 필터 체인을 실행하여 요청 전송, 응답 생성 등의 작업을 수행하도록 한다.
4. 라우트에 정의 된 작업과 필터를 완료한 후 서비스에 요청을 보낸다.
5. 서비스는 응답을 생성하고 다시 API Gateway로 보낸다.
6. 같은 방식으로 필터를 거치고 라우팅 되어 Client에게 응답이 돌아간다.


Spring Cloud Gateway 구현

💡 Gateway Handler Mapping을 구현해 보자.

  1. SpringBoot로 진행하기 위해 의존성을 추가한다.
dependencies {
  implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
  }
  1. Spring Cloud Gateway는 요청을 전달하는 역할만 하기에 Controller가 아닌 Configuration으로 작성한다..route() : Gateway 구성의 시작이다. 간단히 라우트를 식별하기 위한 ID를 받는다.
    predicate -> : 해당 라우트에 적용할 조건을 정의하는 부분이다. 어떤 요청에 어떻게 대응하는지를 정의한다.
    predicate.path() : 요청의 경로에 대한 조건을 설정한다. "/task/"를 통해서 /tast 이후에 어떤 경로에 대해서 일치한다는 의미이다.
    .filters(filter ->) : 이는 요청을 가로채어 수정하거나, 추가적인 동작을 수행하도록 허용한다. 그 조작하는 행동은 rewrite에서 한다.
    .filter.rewritePath() : 여기서 요청의 경로를 조작한다. 여기서 사용된 정규 표현식은 /auth 뒤에 오는 모든 경로를 path라는 변수로 사용한다. 그리고 이를 다시 ${path}의 위치에 넣어주어 요청 경로를 변경합니다.
    ➡ /task/** 로 보내는 요청은 http.//localhost:8081/** 로 보내져, task 쪽에서는 컨트롤러의 URL 구성을 바꿀 필요가 없게 된다.
    .uri : 해당 라우트로 들어온 요청이 전달될 대상 URI를 지정한다. 즉, 어떤 서비스에 이 요청을 보낼 것인지를 결정합니다. 받은 요청이 /task/{id} 의 형태라면 Http://localhost:8082/task/{id} 로 요청이 보내진다.

위 작업들은 yaml파일에서도 작성할 수 있다.


💡 Pre, Post Filter를 구현해 본다.
이는 실행된 경로 및 각 필터의 수행 시간을 확인하여, 요청 처리 및 각 필터의 동작이 원하는 대로 이루어지고 있는지 확인해 보기 위함이다.

먼저, WebFilter Factories에 PreLogging필터를 만들어 본다.
Pre Filter는 클라이언트의 요청이 서비스로 전달되기 전에 실행되는 필터이다. 주로 클라이언트의 인증, 로깅, 헤더 추가 등의 용도로 사용된다.PreLoggingFilter는 GlobalFiter인터페이스를 구현한 클래스이다. 모든 요청에 대해 실행되며, 요청 헤더에 "x-gateway-request-id"와 "x-gateway-request-time"을 추가한다. 마지막으로 체인을 통해 다음 필터로 요청을 전달한다.

exchange.getRequest() : 전달된 HTTP 요청 객체를 받아온다.
mutate() : 현재 요청을 수정하고, 이를 통해 원하는 대로 헤더를 추가하거나 경로를 변경한다. 여기서는 "x-gateway-request-id"와 "x-gateway-request-time"이라는 두 개의 헤더를 추가한다.

마지막에 build( )를 호출하여 변경 사항을 적용한다.


Post Filter는 클라이언트의 요청이 서비스에서 응답을 받은 후에 실행되는 필터이다. 주로 응답에 특정 헤더를 추가하거나, 응답 로깅을 수행하는 등의 후처리 작업을 수행한다.PreLoggingFilter 에서 추가했던 x-gateway-request-id 와 x-gateway-request-time 을 확인하고 요청이 처리되는데 걸리는 시간을 기록하는 필터이다.

.then() : 사용자에게 응답이 전달된 뒤 실행할 내용을 작성하는 공간으로 여기서는 현재 요청의 정보를 추출하고, 시작 시간과 현재 시간을 비교하여 Execution Time을 로깅 하는 코드를 작성했다.

결과

아래 결과는 /api/team/1/tasks로 들어온 요청을 전부 http:/localhost:8082 로 보내도록 설정되었다. 따라서 8082에서 POST된 결과를 8080에서 GET요청을 통해 조회가 되는 모습이다.요청이 들어오면 먼저 PreLoggingFilter가 실행되어 x-gateway-request-id 및 x-gateway-request-time 헤더를 추가하고, 그 후에 PostLoggingFilter가 실행되어 이전 필터에서 추가한 헤더 값을 활용하여 실행 시간을 계산하고 로그로 남기게 된다.위처럼 로그는 요청의 흐름을 따라가며 잘 기록되었으며, 이처럼 필터 간 상호작용 및 전체 서비스 성능을 모니터링할 수 있다.

회고

이번 시간에는 동작을 직접 구현하며 Gateway의 역할에 대한 이해를 더욱 높일 수 있었다.

처음에는 리다이렉트(Redirect)와 게이트웨이(Gateway)가 서로 유사한 역할을 하는 것으로 생각했다. 왜냐하면 둘 다 요청을 다른 장소로 전송하는 역할을 하기 때문이었다. 리다이렉트와 게이트웨이는 모두 요청을 다른 장소로 전송하는 공통된 목적을 가지고 있기 때문이다. 그러나 게이트웨이는 리다이렉트보다 더 다양한 역할을 수행함을 알게 되었다. 프로토콜 간 변환, 데이터 필터링, 보안 검사, 로드 밸런싱 등과 같은 네트워크 관리 및 보안 작업을 주로 수행하는데, 이러한 다양한 기능들은 MSA 환경에서 중요한 역할을 한다.

마지막으로 Gateway를 구축하는 여러 방법 중에 Spring Cloud Gateway는 경량화된 마이크로서비스 환경에서 적합하다는 것을 알게 되었다. 이번 학습을 통해 MSA의 첫걸음을 내딛게 되었고, 이를 계기로 앞으로 더 깊이 있는 MSA 학습을 진행하고자 한다.

참고
https://mangkyu.tistory.com/m/230 - 동작 순서
https://spring.io/projects/spring-cloud-gateway#overview - 개념
https://bit.ly/3GAHDwo - Spring Cloud Gateway 장단점

profile
Slow-starter

0개의 댓글