Spring Cloud Gateway(SCG)란

박세건·2024년 7월 21일
1

기술 학습

목록 보기
6/11

API Gateway에 대해서 먼저 알아보자

API Gateway

API Gateway란, API 생성, 유지 관리, 모니터링, 보호 등을 할 수 있게 해주는 서비스이다.
즉, 클라이언트는 서버로 API 요청을 하게되는데 이때 사이에서 대문(게이트웨이)과 같은 역할을 한다.

  • 모든 클라이언트는 서비스의 엔드포인트 대신 API Gateway로 요청을 전달한다.
  • 설정된 정보에 따라 각각의 엔드포인트로 클라이언트를 대리하여 요청하고 응답받으면 다시 클라이언트에게 전달한다.
    • 이 역할을 프록시 역할이라고 한다.
  • 또한, 대리역할뿐 아니라 인증/인가, 사용량 제어, 요청/응답 변조 등의 다양한 기능을 제공한다.
    • 덕분에 개발자들은 모든 서버마다 위와같은 기능을 구현하지 않아도 되기 때문에 개발 비용도 감소한다.

API가 어떤 역할이 있길래 API Gateway를 사용하는 것인가?

API Gateway 역할 종류

  • API 라우팅
    • 없다면 서버마다 각각 서로의 엔드포인트를 알고있어야함(의존관계 생성 -> 관리의 증가)
    • 있다면 API Gateway의 엔드포인트만 알면됨
  • 인증 및 권한 부여(보안)
  • 속도 제한(트래픽 관리)
  • 부하 분산 (로드밸런싱, 트래픽 관리)
  • 로깅 (모니터링)
  • 서킷 브레이커
    • 장애 발생 시 시스템 보호
  • 캐싱
    • 자주 사용되는 데이터를 캐싱
  • 오케스트레이션
    • 클라이언트 요청을 처리하기 위해 마이크로서비스들을 연계하고 조정
    • 여러개의 마이크로서비스가 연결되어 하나의 비즈니스 프로세스를 수행하는데 이를 오케스트레이션이라고 한다.
  • 메디에이션
    • 클라이언트와 마이크로 서비스간 데이터 형식, 프로토콜 등의 차이를 중재하고 변환
    • 예를들어서 메세지 호출 변화가 있다, 클라이언트에서의 동기적 호출을 비동기 호출로 변경해줄 수 있다.

API 종류

  • HTTP API
    • API 프록시 기능정도만 필요할 때 사용
  • REST API
    • API 관리, 요청/응답에 대한 제어가 필요할때 사용
  • WebSocket API
    • 실시간 애플리케이션에 주로 사용

그렇다면 많은 API Gateway 오픈 소스들이 있는데 왜 SCG을 선택할까?
1. Spring과의 통합성

  • Spring Boot로 구현되어있기 때문에 Spring으로 구현된 프로젝트와 잘 통합된다.
  1. 강력한 라우팅 기능
  • 동적 라우팅, 리본 라우팅과 같은 다양한 라우팅 전략을 지원한다.
  1. 확장성과 유연성
  • 리액티브 프로그래밍 모델을 사용하여 높은 확장성과 유연성을 제공
  1. 운영 및 모니터링 지원
  • 분산 추적 기능을 지원하기때문에 운영 및 모니터링이 용이하다
  1. Spring 생태계의 영향
  • Spring 생태계의 영향을 지원받기 때문에 활발한 커뮤니티가 존재해 정보를 얻기 편리하다.

Spring Cloud Gateway

Spring Cloud Gateway(SCG)란, MSA 환경에서 사용되는 API Gateway중 하나로 Spring 환경의 API Gateway를 뜻한다.

Eureka:

서비스 레지스트리로, 마이크로서비스들이 서로를 찾고 통신할 수 있도록 도와줍니다. 서비스가 시작할 때 자신을 Eureka 서버에 등록하고, 클라이언
트는 이 정보를 통해 서비스를 찾을 수 있습니다.

시스템 구성과 흐름

구성

  • 클라이언트
  • Spring Cloud Gateway
  • MSA

흐름

  1. 모든 마이크로서비스가 시작될 때, 자신의 정보를 Eureka 서버에 등록합니다.
  2. 클라이언트 요청
  • 클라이언트의 요청은 게이트웨이가 받습니다.
  1. 라우팅
  • 클라이언트 요청을 확인하고 적절한 마이크로서비스로 라우팅됩니다.
  1. 필터링
  • 요청과 응답에 대한 필터링을 적용합니다
  • 필터링의 예시로 인증, 권한 확인, 로깅, 모니터링 등이 있습니다.
  1. 마이크로서비스 호출
  • 라우팅된 마이크로서비스에게 요청을 전달합니다.
  1. 응답 반환
  • 마이크로서비스가 처리한 결과를 게이트웨이가 클라이언트에게 반환합니다.

사용방법

  1. Spring Cloud Gateway를 실행시킬 프로젝트 생성
  2. 해당 프로젝트에 dependency 추가
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
  3. application.properties(또는 yml) 파일에 route 정보 설정
    server:
    port: 8000
    spring:
    application:
      name: apigateway-service
    cloud:
      gateway:
        routes:
          - id: {route의 고유 식별자}		// first-service
            uri: {해당 route의 주소} 		 // http://localhost:8081/ (이동될 주소)
            predicates:					// 해당 라우터의 조건 (사용자가 입력한 주소) (/first-service/**로 들어오는 요청은 모두 first-service route로 보낸다.
              - Path=/first-service/**
          */
          - id: {route의 고유 식별자}		// second-service
            uri: {해당 route의 주소} 		 // http://localhost:8082/
            predicates:					// 해당 라우터의 조건 (/second-service/**로 들어오는 요청은 모두 first-service route로 보낸다.
              - Path=/second-service/**
  4. Java Code로 route 정보 설정
    package com.example.apigatewayservice.config;
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    public class FilterConfig {
      @Bean
      public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
          return builder.routes()
                  .route(r -> r.path("/first-service/**")
                          .uri("http://localhost:8081"))
                  .route(r -> r.path("/second-service/**")
                          .uri("http://localhost:8082"))
                  .build();
      }
    }
  5. url로 테스트 하기

왜 application.properties를 설정해주었는데 Java Code로 다시 설정할까?

현재 서비스를 배포해서 운영중에 있다고 생각해보자.
애플리케이션이 구동을 시작할때 application.properties는 한 번 읽혀지고 초기화된다.
즉, 새로운 마이크로서비스가 추가가되고 application.properties을 수정해도 현재 운영중인 서비스에는 적용되지 않는다는 것이다.
이러한 동적인 설정 부분에서는 Java Code 부분으로 작성된 Cofiguration 부분을 수정해주면 동적인 설정과정에서도 유연하게 라우팅을 적용시킬 수 있다.


Spring Cloud Gateway + Eureka Server = LoadBalancing


✅ 전체 구조

  • 클라이언트 → Spring Cloud Gateway → Eureka 등록 서버 → 로드밸런싱 처리

✅ 세부 동작

① 서비스 등록 (Eureka Server)

  • 서비스 인스턴스(A-1, A-2, A-3)가 Eureka에 등록
  • Eureka가 인스턴스 상태 관리

② 요청 처리 (Spring Cloud Gateway)

  • 클라이언트가 Gateway에 요청 전송
  • Gateway가 Eureka에서 인스턴스 목록 조회
  • 살아있는 인스턴스 목록 수신

③ 로드밸런싱 (LoadBalancer)

  • LoadBalancerClient가 인스턴스를 선택해 요청 전달
  • 기본 로드밸런싱 방식은 Round Robin
    • 첫 번째 요청 → A-1
    • 두 번째 요청 → A-2
    • 세 번째 요청 → A-3
    • 네 번째 요청 → A-1 (순환 반복)

✅ 역할별 정리

구성 요소역할
Eureka Server서비스 인스턴스 상태 관리
Spring Cloud Gateway클라이언트 요청 수신, 인스턴스 조회, 로드밸런싱 수행
LoadBalancer인스턴스 선택 및 분산 처리 (기본 Round Robin)

✅ 로드밸런싱 방식

방식설명
Round Robin순서대로 인스턴스에 요청 분배 (기본값)
Random무작위로 인스턴스에 요청 분배 (설정 가능)
커스텀사용자 정의 로직으로 분배 (직접 구현 필요)

📕추가적인 로드밸런싱 방식

Round Robin과 Random 방식외에도 Least Connections 와 Source IP Hash 방법 등과 같은 효과적인 방식이 존재한다.
Least Connections : 적은 연결을 보유하고 있는 서버에게 할당
Source IP Hash : 특정 IP에 해당하는 서버로 할당
하지만, Spring Cloud Gateway에서 기보적으로 제공하는 방식은 Round Robin과 Random 방식이기에 각각의 방식은 커스텀 구현해야한다.


✅ 한 줄 요약

  • Spring Cloud Gateway는 Eureka에서 서비스 목록을 받아 LoadBalancer로 요청을 분산 처리한다.

profile
멋있는 사람 - 일단 하자

0개의 댓글