이전 게시물에서 마이크로서비스 간의 통신을 구현했습니다.
현재까지 구현 내용은 다음과 같습니다.
여기서 점선은 아직 구현되지 않은 부분을 의미합니다.
이번 게시물에서 구현할 내용은 API Gateway 입니다.
API Gateway는 MSA를 구성하는 데에 필요한 컴포넌트 중 하나며 마치 프록시 서버처럼 동작합니다.
Client들이 마이크로 서비스 API에 접근하기 전에 접근하는 Edge 서버.
인증 및 권한, 모니터링, logging 등 추가적인 기능을 가짐.
Monolithic Architecture와 달리 MSA는도메인별로 하나 이상의 서버가 따로 존재하며
다수의 end point를 관리하고 MSA 환경에서 서비스에 대한 도메인들을 하나로 통합 관리 할 수 있는 것이 API Gateway 입니다.
오픈소스로는 Kong, API Umbrella 등이 있으며 대표적으로 Netflix의 Zuul이 있습니다.
Spring에서는 Spring Cloud Gateway로 대용량 트래픽 처리와 리액티브 프로그래밍 모델을 활용하는 현대적인 마이크로서비스 아키텍처에 적합한 기술 스택입니다.
아키텍처 | 기술스택 | 성능 | 확장성 | 지원 | |
---|---|---|---|---|---|
Netflix Zuul | Servlet 기반의 동기 방식 | Spring MVC | Thread pool, 블로킹 발생 | 동기 방식으로 낮은 확장성 | Spring에서 지원 중단 |
Spring Cloud Gateway | Netty 기반의 비동기/Non-blocking 방식 | Spring WebFlux | Event-loop 방식 | 비동기 방식으로 높은 확장성 | Spring에서 적극 권장 |
따라서 많은 레퍼런스를 참조할 수 있는 Spring Cloud Gateway로 API 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'
}
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 구현에서 설명했으므로 라우팅 관련 설정만 살펴보겠습니다.
lb://
프로토콜 사용 시 (예: lb://{서비스이름}
):Spring Cloud Gateway를 사용하여 API Gateway를 구현했습니다. 주요 내용을 요약하면 다음과 같습니다:
spring-cloud-starter-gateway
의존성 추가application.yml
에서 라우팅 설정, Eureka 클라이언트 설정, Actuator 설정 등을 구성향후 개선 방향으로는 다음과 같은 사항을 고려할 수 있습니다:
1. 보안 강화: JWT 토큰 검증, Rate Limiting 등의 추가
2. 로깅 및 모니터링 강화: 상세한 요청/응답 로깅, 성능 메트릭 수집
3. 동적 라우팅: 런타임에 라우팅 규칙을 변경할 수 있는 기능 추가
4. 서킷 브레이커 패턴 적용: 장애 전파 방지 및 시스템 안정성 향상