Skip to main content
LadeStack LogoLadeStack
Microservices 약 12분 소요 2024년 9월 15일

마이크로서비스를 위한 API 게이트웨이 구축: 라우팅, 인증, 속도 제한 및 복원력

리버스 프록시, 분산 인증, Redis 토큰 버킷 속도 제한, 서킷 브레이커, Envoy 구성 및 서비스 메시 비교를 다루는 엔터프라이즈급 API 게이트웨이 설계 가이드.

API 게이트웨이 마이크로서비스 아키텍처 다이어그램

1. 소개: 분산 마이크로서비스에서 API 게이트웨이가 필수적인 이유

분산 마이크로서비스 아키텍처에서 클라이언트 애플리케이션(웹 브라우저, 모바일 앱, 서드파티 파트너)이 수십 개의 내부 개별 서비스와 직접 통신하는 구조는 심각한 안티패턴입니다.

직접 통신 모델은 다음과 같은 문제를 야기합니다:

  • 클라이언트와 백엔드 간의 과도한 결합: 서비스가 분할되거나 엔드포인트 URL이 변경될 때마다 모든 클라이언트 앱을 재배포해야 합니다.
  • 보안 공격 표면의 무분별한 확장: 모든 내부 마이크로서비스가 공용 인터넷에 노출되어 개별 방화벽, CORS 설정 및 SSL/TLS 인증서 관리가 파편화됩니다.
  • 인증 및 트래픽 제어 로직의 중복: 각 팀이 JWT 검증과 요청 제한 로직을 개별 구현하면서 보안 취약점이 발생합니다.
  • 네트워크 지연 시간 누적: 모바일 클라이언트가 단일 대시보드를 렌더링하기 위해 10개 이상의 HTTP 호출을 직렬로 수행하게 됩니다.
직접 연결 vs API 게이트웨이 패턴
=================================
직접 연결 모델 (안티패턴):
[모바일 클라이언트] ──┬──► [인증 서비스 :8081]
                     ├──► [주문 서비스 :8082]
                     ├──► [결제 서비스 :8083]
                     └──► [재고 서비스 :8084]

API 게이트웨이 모델 (권장 패턴):
                     ┌────────────────────────────────────────────────────────┐
                     │                 API 게이트웨이 (:443)                   │
                     │  - SSL 종료 & CORS 보안 정책                           │
                     │  - JWT 암호화 검증 & 내부 헤더 전파                    │
                     │  - Redis 기반 분산 토큰 버킷 속도 제한                 │
                     │  - 지능형 라우팅 & 타임아웃 / 서킷 브레이커            │
                     └──────────────────────────┬─────────────────────────────┘
                                                │ 사설 VPC 네트워크 (mTLS)
                           ┌────────────────────┼────────────────────┐
                           ▼                    ▼                    ▼
                   [인증 서비스]            [주문 서비스]        [결제 서비스]

API 게이트웨이는 시스템 경계에서 단일 진입점(리버스 프록시) 역할을 수행하여 공통 관심사를 중앙에서 집중 처리합니다.


2. 엔터프라이즈 게이트웨이 핵심 기능 아키텍처

프로덕션 환경을 지원하는 API 게이트웨이는 다음 핵심 기능을 반드시 제공해야 합니다:

기능 계층 게이트웨이 책임 구현 메커니즘 / 프로토콜
리버스 프록시 & 라우팅 클라이언트 요청 경로를 사설 백엔드 서비스로 중계 프리픽스 매칭, 정규식 라우팅, 가중치 기반 카나리 라우팅
에지 인증 & 토큰 유효성 검사 유입된 요청의 서명 검증 및 인증 메타데이터 삽입 JWT RS256/EdDSA 검증, JWKS 캐싱, mTLS 상호 인증
트래픽 거버넌스 & DoS 보호 테넌트별 할당량 관리 및 폭주 트래픽 차단 Redis 토큰 버킷 알고리즘, 슬라이딩 윈도우
복원력 (Resilience) 장애 전파 차단 및 일시적 네트워크 지연 완화 요청 타임아웃, 지수 백오프 재시도, 서킷 브레이커
분산 추적 (Observability) 엔드투엔드 트랜잭션 추적성 확보 W3C TraceContext (traceparent), OpenTelemetry 연동
프로토콜 변환 외부와 내부 통신 프로토콜 분리 외부 HTTP/1.1・HTTP/2를 내부 고성능 gRPC/Protobuf로 변환

3. 인증 및 심층 방어 (Defense in Depth)

핵심 설계 원칙: 게이트웨이 인증은 다운스트림 인가를 대체하지 않는다

많은 개발팀이 “게이트웨이에서 토큰을 검증했으므로 내부 마이크로서비스는 인가를 검사할 필요가 없다”는 위험한 가정을 합니다.

게이트웨이가 손상되거나 내부 네트워크를 통해 서비스가 직접 호출될 경우 모든 다운스트림 시스템이 무방비 상태가 됩니다. 반드시 심층 방어(Defense in Depth) 원칙을 적용해야 합니다:

심층 방어 인증 아키텍처
----------------------
[클라이언트]
      │ 1. Authorization: Bearer <JWT>
      ▼
[API 게이트웨이]
      │ 2. 로컬 캐시된 JWKS 공개키로 JWT 암호화 서명 검증
      │ 3. 토큰 만료(exp) 및 발급자(iss) 확인 후 위조 토큰 즉시 401 차단
      │ 4. 검증된 클레임을 신뢰할 수 있는 내부 헤더로 변환하여 전달:
      │    - X-User-Id: 98412
      │    - X-User-Roles: billing_admin,user
      │    - X-Tenant-Id: tenant_corp_a
      ▼
[다운스트림 마이크로서비스 (주문/결제)]
      │ 5. mTLS 연결 확인
      │ 6. X-User-Roles 헤더를 기반으로 세부 리소스 인가(Authorization) 독립 판별
      │ 7. 비즈니스 로직 실행

4. 분산 속도 제한: Redis 토큰 버킷 알고리즘

단일 서버 메모리 기반 속도 제한은 인스턴스가 수평 확장(Auto-scaling)되는 클라우드 환경에서 트래픽을 제어하지 못합니다. 인스턴스가 10대로 증가하면 허용량이 10배로 늘어나는 부작용이 발생합니다.

중앙 집중식 Redis 클러스터와 원자적(Atomic) Lua 스크립트를 사용하여 완벽한 토큰 버킷 속도 제한을 구현합니다:

-- Redis Token Bucket Rate Limiting (Atomic Lua Script)
-- KEYS[1]: 속도 제한 키 (예: ratelimit:tenant_123:orders)
-- ARGV[1]: 버킷 최대 용량 (Max Burst)
-- ARGV[2]: 토큰 충전 속도 (초당 토큰 수)
-- ARGV[3]: 현재 유닉스 타임스탬프 (초)
-- ARGV[4]: 요청 토큰 수 (기본 1)

local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local fill_rate = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])

local data = redis.call('HMGET', key, 'tokens', 'last_updated')
local tokens = tonumber(data[1])
local last_updated = tonumber(data[2])

if not tokens then
    tokens = capacity
    last_updated = now
else
    local elapsed = math.max(0, now - last_updated)
    tokens = math.min(capacity, tokens + (elapsed * fill_rate))
    last_updated = now
end

if tokens >= requested then
    tokens = tokens - requested
    redis.call('HMSET', key, 'tokens', tokens, 'last_updated', last_updated)
    redis.call('EXPIRE', key, math.ceil(capacity / fill_rate) * 2)
    return {1, math.floor(tokens)} -- 1 = 허용, 남은 토큰 수
else
    redis.call('HMSET', key, 'tokens', tokens, 'last_updated', last_updated)
    return {0, 0} -- 0 = 거부 (429 Too Many Requests)
end

5. 복원력 패턴: 타임아웃, 재시도, 서킷 브레이커

서킷 브레이커 상태 전이 모델
----------------------------
       ┌─────────── 오류율 임계치 초과 (예: 50% 실패) ───────────┐
       │                                                         │
       ▼                                                         │
 ┌───────────┐       쿨다운 대기 시간 경과 (예: 30초)      ┌───────────┐
 │   OPEN    │ ─────────────────────────────────────────► │ HALF-OPEN │
 └───────────┘                                            └───────────┘
       ▲                                                         │
       │             ┌───────── 테스트 호출 성공 ────────────────┘
       │             ▼
 ┌───────────┐
 │  CLOSED   │ (정상 트래픽 통과)
 └───────────┘
  1. 상류 타임아웃 제한: 게이트웨이의 타임아웃은 항상 다운스트림 내부 타임아웃보다 짧아야 클라이언트 커넥션 풀 고갈을 방지할 수 있습니다.
  2. 멱등성(Idempotency) 기반 재시도: GET, PUT, DELETE와 같은 안전한 멱등성 요청만 자동 재시도해야 합니다. POST 결제 요청을 무분별하게 재시도하면 중복 결제가 발생합니다.
  3. 서킷 브레이커: 백엔드 서비스가 지속적으로 응답하지 않을 때 요청을 즉시 차단(OPEN)하여 시스템 전체 마비를 막습니다.

6. 게이트웨이 기술 비교: Envoy vs NGINX vs Kong

비교 항목 Envoy Proxy NGINX (Open Source / Plus) Kong Gateway
구현 언어 C++ (초저지연, 예측 가능한 메모리) C (검증된 이벤트 기반 아키텍처) Lua / OpenResty (NGINX 코어)
구성 업데이트 동적 xDS API (무중단 핫 리로드) 정적 파일 (설정 변경 시 프로세스 리로드) 동적 REST API 및 선언적 decK 도구
지원 프로토콜 HTTP/1.1, HTTP/2, HTTP/3, gRPC HTTP/1.1, HTTP/2, gRPC 프록시 HTTP/1.1, HTTP/2, gRPC
확장 방식 WebAssembly (Wasm) 필터, C++ C 모듈, njs (자바스크립트) Lua 플러그인, Wasm 플러그인
추천 환경 클라우드 네이티브, 쿠버네티스 인그레스 고성능 정적 웹 서빙, 경량 프록시 플러그인 생태계를 활용한 엔터프라이즈

7. API 게이트웨이 vs 서비스 메시 (Service Mesh)

두 기술은 상호 배타적인 것이 아니라 서로 보완하는 관계입니다:

  • API 게이트웨이 (North-South 트래픽): 외부 공용 인터넷에서 내부 VPC로 유입되는 경계 트래픽을 통제합니다. 외부 인증, 속도 제한, API 수익화 및 클라이언트 계약을 담당합니다.
  • 서비스 메시 (East-West 트래픽): 내부 마이크로서비스 간의 통신(Istio, Linkerd)을 관리합니다. 서비스 간 자동 mTLS 암호화, 세밀한 카나리 배포 트래픽 분할, 세부 메트릭 수집을 전담합니다.

8. 요약 및 프로덕션 배포 체크리스트

  1. 고가용성 확보: 여러 가용 영역(AZ)에 걸쳐 게이트웨이 인스턴스를 분산하고 클라우드 로드밸런서로 다중화합니다.
  2. 비동기 JWKS 서명 검증: JWT 검증 시 외부 인증 공급자(IdP)를 매번 호출하지 않고 로컬 캐시 공개키로 처리합니다.
  3. 다운스트림 심층 방어: 내부 마이크로서비스 간에도 mTLS 및 권한 검증을 유지합니다.
  4. 분산 추적 표준화: W3C TraceContext 규격을 준수하여 모든 다운스트림 호출 체인을 하나의 트랜잭션으로 가시화합니다.

More Engineering Articles