[Spring Cloud] Spring Cloud Gateway - 기본 개념

mrcocoball·2024년 1월 2일
0

Spring Cloud

목록 보기
1/8
post-custom-banner

해당 포스트는 Spring Cloud에 속한 기술들에 대한 개념과 주요 기술에 대해 알아보고 실무에 적용했었던 내용을 정리하는 포스트입니다.

[이미지 출처 : https://www.connecting-software.com/blog/what-is-an-api-gateway-how-it-can-actually-deliver-practical-results/]

1. 개요

API 게이트웨이란

API 게이트웨이(패턴) 는 마이크로서비스 관리 / 운영을 위한 플랫폼 패턴이며 해당 패턴에 필요한 기능들을 제공하는 서버를 일컫습니다.
API 게이트웨이는 개별 서비스의 앞 단에서 모든 서비스들의 엔드포인트를 단일화하고 다음과 같은 필수 기능 요소들을 제공합니다.

  • 인증과 인가 : 모든 서비스들에 대한 접근에 있어서 단일 진입점에서 인증과 인가 처리를 진행
  • API 요청 로드밸런싱 및 라우팅 : API 요청을 식별하여 적절한 마이크로서비스로 전달
  • QoS(Quality of Service) : 안정적인 서비스 제공 및 네트워크 품질을 관리하며 사용자 / 클라이언트 / API 단위로 접속 제어
  • 로깅 및 모니터링 : API 요청에 대한 로깅 / 모니터링 기능 지원
  • 입력 유효성 검사 : API 요청의 적절한 형식과 필수 데이터 포함 여부를 식별 및 관리

API 게이트웨이의 장단점

API 게이트웨이를 사용함으로서 다음과 같은 장점을 얻을 수 있습니다.

  • 애플리케이션의 내부 구조를 캡슐화 : 클라이언트는 특정 서비스를 호출하지 않고 단순히 게이트웨이와 통신하며, API 게이트웨이는 각 종류의 클라이언트에 특정 API를 제공
  • 클라이언트와 애플리케이션 간의 왕복 횟수가 감소하며, 클라이언트 코드 단순화

하지만 장점이 있다면 당연히 단점도 있겠죠. API 게이트웨이는 앞서 소개해드린 장점 외에 단점도 존재합니다.

  • 개발, 배포 및 관리해야 하는 지점이 증가
  • 각 마이크로서비스의 Endpoint를 노출하기 위해 API 게이트웨이를 업데이트해야 하는데 이로 인해 개발 병목 현상이 발생할 수 있음

그러나 단점이 있음에도 장점이 뚜렷하기 때문에 오늘날 마이크로서비스 아키텍처에서 API 게이트웨이는 반드시 필요한 요소로 존재하고 있습니다.

Spring Cloud Gateway란

Spring Cloud Gateway는 Spring Framework에서 제공하는 오픈 소스 기반의 Gateway 서비스입니다.
Spring Cloud Gateway 이전에는 Spring Cloud Zuul이 있었으며 Zuul의 패치가 중단됨에 따라 Spring Cloud Gateway로의 이전이 이뤄졌다고 합니다.

Spring Cloud Zuul과 Spring Cloud Gateway의 가장 큰 차이점은 다음과 같습니다.

  • 기반 웹 서버 : Zuul은 Tomcat, Spring Cloud Gateway(이하 SCG)는 Netty
  • 동기 / 비동기 방식 : Zuul은 동기 방식, Netty는 비동기 방식
  • 웹 프레임워크 : Zuul은 Spring WEB MVC 기반이지만 SCG는 Spring WebFlux 기반

Spring Cloud Gateway는 비동기 방식을 통해 수많은 요청을 빠르게 처리할 수 있으며 다른 Spring Cloud 기반 기술들과 통합이 잘 되어 있어 다양한 기술적 연계가 가능합니다.

2. 아키텍처와 특징

아키텍처 특징

SCG의 개념도는 다음과 같습니다.

SCG를 구성하는 주요 3요소로는 Route, Predicate, Filters가 있으며 사용자의 요청이 각 컴포넌트를 거쳐 라우팅됩니다.

Route

Route는 고유 ID + 목적지 URI + Predicate + Filter로 구성되며, 아래에서 소개할 Predicate + Filter의 묶음이자 라우팅이 될 규칙이라고 할 수 있습니다.
Route를 통해 SCG로 요청된 URI의 조건이 Predicate를 통과하여 참인 경우 매핑된 해당 경로로 매칭됩니다.

Predicate

Predicate는 주어진 요청이 주어진 조건을 충족하는지 테스트하는 구성 요소이며, 하나 이상의 조건자를 정할 수 있습니다.
만약 Predicate에 매칭되지 않을 경우 SCG 자체적으로 HTTP 404 Not Found로 응답합니다.

Filter & Filter Chain

Filter & Filter Chain은 SCG를 통해 들어오는 요청이나 반환되는 응답에 대해 전처리 / 후처리를 담당합니다.
이 중에서 Proxy Filter는 프록시 요청이 처리될 떄 수행되는 필터입니다.

앞서 소개한 Route, Predicate, Filters의 예시를 보여드리면 다음과 같습니다. (application.yaml)

spring:
  cloud:
    gateway:
      # 먼저 선언한 순서대로 필터가 적용됨 route 1 -> route 2
      routes:
      	# route 1, route의 id는 sample-internal
        - id: sample-internal
          uri: http://localhost:8081
          predicates:
            - Path=/sample/api/v1/internal/** # /sample/api/v1/internal/** 로 들어오는 요청에 반응
          filters:
            - NotAllowedURIExceptionFilter # filter 로직 적용 (커스텀 필터)
        # route 2, route의 id는 sample
        - id: sample
          uri: http://localhost:8081
          predicates:
            - Path=/sample/** # /sample/** 로 들어오는 요청에 반응
          filters:
            - RewritePath=/sample/(?<segment>.*), /$\{segment} # filter 로직 적용 (RewritePath 필터)

3. Predicates

Predicates는 주어진 요청이 주어진 조건을 충족하는지 테스트하는 구성 요소로, 크게 시간 / URI / 요청 / 네트워크 관련으로 분류를 할 수 있습니다.

시간 관련

  • Before : 요청이 특정 시간대 이전에 들어온 것인지 확인
  • After : 요청이 특정 시간대 이후에 들어온 것인지 확인
  • Between : 요청이 특정 시간대 사이에 들어온 것인지 확인

URI 관련

  • Path : 요청이 특정 경로로 들어왔는지 확인
  • Query : 요청에 특정 파라미터가 포함되어 있는지 확인

요청 관련

  • Cookie : 요청에 특정 쿠키가 담겨 있는지 확인
  • Header : 요청에 특정 헤더가 있는지 확인
  • Method : 요청이 특정 HTTP 메서드로 들어왔는지 확인
  • Weight : 전체 트래픽에 대해 그룹별 가중치를 두어 그룹별로 요청을 분산시킴

네트워크 관련

  • Host : 요청이 특정 호스트로 들어왔는지 확인
  • RemoteAddr : 요청이 특정 원격 주소로 들어왔는지 확인
    • SCG가 프록시 계층 뒤에 있으면 실제 클라이언트 IP 주소와 일치하지 않을 수 있음
    • 이 경우 사용자 지정을 설정하여 원격 주소를 확인하는 방법을 설정할 수 있음 (RemoteAddressResolver, XForwaredRemoteAddressResolver)

4. Filters

Filter & Filter Chain은 SCG를 통해 들어오는 요청이나 반환되는 응답에 대해 전처리 / 후처리를 담당하며, 특정 Route에 적용할 수 있는 Gateway Filter전역적으로 적용되는 Global Filter로 분류합니다.

Gateway Filter

  • 요청 / 응답 관련
    • AddRequestHeader / AddResponseHeader : 요청 / 응답 헤더를 추가
    • AddRequestParameter : 요청 시 파라미터를 추가
    • RemoveRequestHeader / RemoveResponseHeader : 요청 / 응답 헤더를 삭제
    • RemoveRequestParameter : 요청 시 파라미터를 삭제
    • DedupeResponseHeader : 이름이 공백인 헤더 이름 목록을 포함할 수 있음
    • MapRequestHeader : 새롭게 명명된 헤더를 만들고 기존에 들어온 요청에 명명된 헤더에서 값을 추출하여 넣음
    • PrefixPath : 모든 요청의 경로에 접두사를 붙일 수 있음
    • RewritePath : 특정 경로를 새 경로로 변환
    • RewriteLocationResponseHeader : 응답 헤더의 값 중 Location을 수정
    • RewriteResponseHeader : 응답 헤더 값을 수정
    • RedirectTo : 300번대 HTTP 상태값에 대해 특정 URI로 리다이렉션할 수 있도록 설정
    • SaveSession : Spring Session 사용 시 유용하며 전달된 호출을 만들기 전에 세션 상태가 저장되었는지 확인
    • SecureHeaders : 각종 보안 관련 헤더를 추가
    • SetPath : 요청 경로를 특정 경로로 변경, 템플릿 세그먼트 허용
    • SetRequestHeader / SetResponseHeader : 요청 / 응답 헤더를 지정된 이름으로 대체함
    • SetStatus : 특정 HTTP 상태로 설정
    • StripPrefix : 요청에서 특정 수만큼 경로를 제거함
    • Retry : 재시도해야 하는 횟수, 상태, 메서드, 예외, 백오프 등을 설정
    • RequestSize : 요청 크기가 허용 가능한 한도보다 큰지 체크
    • SetRequestHost : 기존 호스트 헤더를 지정된 값으로 대체할 수 있음
  • 예외 관련
    • CircuitBreaker : Spring Cloud Circuit Breaker 연동, 게이트웨이 경로를 Circuit Breaker로 래핑함
    • FallbackHeaders : FallbackHeaders에 전달된 요청의 헤더에 Circuit Breaker 실행 예외 세부 정보를 추가할 수 있음
  • 네트워크 관련
    • PreserveHostHeader : HTTP 클라이언트가 결정한 호스트 헤더가 아닌 원래 호스트 헤더를 보내야하는지 결정하기 위해 라우팅 필터가 검사하는 요청 속성을 설정
  • 부하 처리 관련
    • RequestRateLimiter : RateLimiter를 통해 현재 요청을 진행할 수 있는지 확인, 진행할 수 없을 경우 HTTP 429 - Too Many Requests 상태가 반환됨
  • 기본 필터 : 모든 경로에 적용하기 위한 필터를 default-filters에 묶어서 지정

Global Filter

  • LoadBalancerClientFilter : URL에 lb 체계가 있는 경우 Spring Cloud를 사용하여 LoadBalancerClient 이름을 실제 호스트 및 포트로 확인하고 동일한 속성의 URI를 바꿈
  • ReactiveLoadBalancerClientFilter
  • WebClientHttpRoutingFilter
  • NettyWriteResponseFilter
  • RouteToRequestUrlFilter
  • GatewayMetricFilter : Spring Boot Actuator와 연결, spring.cloud.gateway.metrics.enabled 속성 설정 시 작동됨. 다음 지표가 Actuator에 추가됨
    • routeId : 경로 ID
    • routeUri : API가 라우팅 되는 URI
    • outcome
    • status
    • httpStatusCode
    • httpMethod

Appendix. 출처

https://cloud.spring.io/spring-cloud-gateway/reference/html/
https://s-core.co.kr/insight/view/spring-cloud-gateway-%EA%B8%B0%EB%B0%98%EC%9D%98-api-%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%9B%A8%EC%9D%B4-%EA%B5%AC%EC%B6%95/
https://nginxstore.com/blog/api-gateway/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EA%B5%AC%EC%B6%95%EC%9D%84-%EC%9C%84%ED%95%9C-api-gateway-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0/

profile
Backend Developer
post-custom-banner

0개의 댓글