[Spring Cloud]API Gateway - MSA 적용기(3)

HW·2024년 8월 31일
0

MSA

목록 보기
3/4

서론

이전 게시물에서 마이크로서비스 간의 통신을 구현했습니다.
현재까지 구현 내용은 다음과 같습니다.

여기서 점선은 아직 구현되지 않은 부분을 의미합니다.
이번 게시물에서 구현할 내용은 API Gateway 입니다.

본론

API Gateway는 MSA를 구성하는 데에 필요한 컴포넌트 중 하나며 마치 프록시 서버처럼 동작합니다.

API Gateway

Client들이 마이크로 서비스 API에 접근하기 전에 접근하는 Edge 서버.
인증 및 권한, 모니터링, logging 등 추가적인 기능을 가짐.

Monolithic Architecture와 달리 MSA는도메인별로 하나 이상의 서버가 따로 존재하며
다수의 end point를 관리하고 MSA 환경에서 서비스에 대한 도메인들을 하나로 통합 관리 할 수 있는 것이 API Gateway 입니다.

오픈소스로는 Kong, API Umbrella 등이 있으며 대표적으로 Netflix의 Zuul이 있습니다.
Spring에서는 Spring Cloud Gateway로 대용량 트래픽 처리와 리액티브 프로그래밍 모델을 활용하는 현대적인 마이크로서비스 아키텍처에 적합한 기술 스택입니다.

아키텍처기술스택성능확장성지원
Netflix ZuulServlet 기반의 동기 방식Spring MVCThread pool, 블로킹 발생동기 방식으로 낮은 확장성Spring에서 지원 중단
Spring Cloud GatewayNetty 기반의 비동기/Non-blocking 방식Spring WebFluxEvent-loop 방식비동기 방식으로 높은 확장성Spring에서 적극 권장

따라서 많은 레퍼런스를 참조할 수 있는 Spring Cloud Gateway로 API Gateway를 구현하겠습니다.

Spring Cloud Gateway

![[spring-cloud-gateway-diagram.png]]
Spring Cloud Gateway의 동작 과정입니다.
1. 클라이언트가 gateway로 네트워크 요청을 보냅니다.
2. 게이트웨이는 Gateway Handler Mapping으로 매칭시키기 위한 조건(Predicate)들을 확인합니다. 예를 들어, URL의 경로 세그먼트나 요청의 HTTP 메서드를 기준으로 매칭합니다.
3. 매칭이 되면, Gateway Web Mapping 로직을 실행합니다. 예를 들어, 요청에 쿼리 파라미터를 추가합니다.
4. 필터된 요청을 프록시된 서비스로 라우팅합니다.
5. 서비스가 실행되고 응답을 반환합니다.
6. 게이트웨이가 응답을 받고, 응답을 클라이언트에게 반환하기 전에 Post-request 로직을 실행합니다. 예를 들어, 클라이언트에게 반환하기 전에 원하지 않는 응답 헤더를 제거할 수 있습니다.

의존성 추가

spirng-cloud-starter-gateway 의존성을 추가해줍니다.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-actuator'
	implementation 'org.springframework.cloud:spring-cloud-starter-config'
	implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
	implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}

라우팅 및 application.yml 설정

server:
  port: 21999

spring:
  application:
    name: api-gateway
  config:
    import: optional:configserver:http://localhost:8888
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
          - id: user-service
            uri: http://localhost:21001
            predicates:
              - Path=/api/v1/users/**
          - id: language-service
            uri: http://localhost:21003
            predicates:
              - Path=/api/v1/languages/**

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:21000/eureka

management:
  endpoints:
    web:
      exposure:
        include: "*"

spring.cloud.gateway 하위에 라우팅 관련 설정과 함께 아래에 Eureka, Actuator 관련 설정을 진행했습니다.

Eureka, Actuator 관련 설정은 이전 Chapter의 Eureka 구현에서 설명했으므로 라우팅 관련 설정만 살펴보겠습니다.

  • spring.cloud.gateway.routes.id
    - 각 라우트에 고유한 식별자를 할당합니다.
    - 여러 라우팅 규칙을 구분하고 관리하는 데 도움이 됩니다.
  • spring.cloud.gateway.routes.uri
    • 요청이 라우팅될 대상 URI를 지정합니다.
      - lb:// 프로토콜 사용 시 (예: lb://{서비스이름}):
      - Eureka Server를 통한 서비스 디스커버리가 가능합니다.
      - 가용한 서비스 인스턴스 간 자동 로드 밸런싱이 이루어집니다.
  • spring.cloud.gateway.routes.predicates
    • 들어오는 요청에 기반하여 라우트 활성화 조건을 정의합니다.
      - 특정 요청에 대해 어떤 라우트를 사용할지 결정합니다.

결론

Spring Cloud Gateway를 사용하여 API Gateway를 구현했습니다. 주요 내용을 요약하면 다음과 같습니다:

  1. API Gateway의 필요성:
    • MSA 환경에서 다수의 엔드포인트를 통합 관리하고 추가적인 기능(인증, 모니터링, 로깅 등)을 제공하는 중요한 컴포넌트입니다.
  2. Spring Cloud Gateway 선택:
    • Netflix Zuul과 비교하여 비동기/Non-blocking 방식, 높은 성능과 확장성, Spring의 적극적인 지원 등의 이점으로 선택했습니다.
  3. 구현 과정:
    • spring-cloud-starter-gateway 의존성 추가
    • application.yml에서 라우팅 설정, Eureka 클라이언트 설정, Actuator 설정 등을 구성
  4. 주요 설정 설명:
    • 라우트 ID, URI, 조건(predicates) 등을 설정하여 각 마이크로서비스로의 라우팅 규칙을 정의했습니다.

향후 개선 방향으로는 다음과 같은 사항을 고려할 수 있습니다:
1. 보안 강화: JWT 토큰 검증, Rate Limiting 등의 추가
2. 로깅 및 모니터링 강화: 상세한 요청/응답 로깅, 성능 메트릭 수집
3. 동적 라우팅: 런타임에 라우팅 규칙을 변경할 수 있는 기능 추가
4. 서킷 브레이커 패턴 적용: 장애 전파 방지 및 시스템 안정성 향상

profile
예술융합형 개발자🎥

0개의 댓글