1. API 게이트웨이란?
API 게이트웨이는 클라이언트의 요청을 받아 적절한 백엔드 서비스로 라우팅해주는 중간 서버이다.
MSA 환경에서 수많은 마이크로서비스가 존재할 때, 클라이언트가 각 서비스의 주소를 모두 알 필요 없이 게이트웨이라는 단일 진입점만 보면 된다
주요 기능
- 라우팅: 클라이언트의 요청을 알맞은 백엔드 서비스로 전달
- 인증 및 권한 부여: 들어오는 요청에 대한 인증과 권한을 중앙에서 검증
- 로드 밸런싱: 여러 서비스 인스턴스로 부하를 분산시켜 준다
- 모니터링 및 로깅: 서비스 요청과 응답을 로깅하고 상태를 모니터링
- 요청/응답 변환: 필요에 따라 요청이나 응답 데이터를 변환하거나 필터링
2. Spring Cloud Gateway (SCG)
Spring 환경에서는 주로 Spring Cloud Gateway를 사용하고 클라이언트 요청 라우팅 및 강력한 필터링 기능을 제공
- 요청의 URL 패턴에 따라 동적으로 라우팅을 수행
- 요청 전후에 다양한 작업을 처리할 수 있는 필터 체인(Filter Chain)을 제공
- Spring Cloud Netflix 패키지의 일부로서 마이크로서비스 아키텍처에서 널리 활용
3. SCG 필터(Filter)의 이해
게이트웨이의 꽃은 단연 '필터'입니다. 적용 범위에 따라 모든 요청에 동작하는 Global Filter와 특정 라우트에만 적용되는 Gateway Filter로 나뉩니다.
Pre 필터 vs Post 필터
- Pre 필터: 요청이 백엔드 서비스로 처리되기 전에 실행.
- 요청을 가로채서 로깅이나 인증 등의 선행 작업을 한 후,
chain.filter(exchange)를 통해 다음 체인으로 넘깁니다. 비동기 처리를 위한then메서드가 필요 없다.
- Post 필터: 요청이 처리되고 응답이 클라이언트로 반환되기 전에 실행. 체인의 다음 필터가 완료된 후 실행되어야 하므로
chain.filter(exchange).then(Mono.fromRunnable(...))형태로 응답 완료 후의 추가해야한다
💡 현업 필수 지식 (Practical Tips)
1. Eureka와의 통합
실무에서는 하드코딩된 IP가 아닌, Eureka 같은 서비스 디스커버리와 통합하여 동적으로 서비스 인스턴스를 조회하고 라우팅/로드밸런싱을 수행합니다. (예: uri: lb://user-service 형태로 구성)
2. 레거시 시스템과 Zuul (Spring Boot 2)
대부분의 회사가 운영 중인 레거시 시스템은 Spring Boot 2 기반일 가능성이 크다.
따라서 과거에 널리 쓰였던 Netflix Zuul에 대해서도 알아두는 것이 좋습니다.
코드보다는 "클라우드 게이트웨이와 같은 역할을 하는 구형 기술이구나" 정도로 기능을 이해하고 넘어가면 된다.
3. 리액티브 프로그래밍 (WebFlux) 기반
Spring Cloud Gateway는 Spring WebFlux 위에서 동작합니다. 따라서 필터 구현 시 Mono (0~1개의 데이터를 비동기 처리)와 ServerWebExchange (HTTP 요청/응답 캡슐화 객체)를 다룰 줄 알아야 합니다.
내가 알아야 될 개발 지식 정리
1. 공통 관심사의 중앙화 (Cross-Cutting Concerns)
마이크로서비스가 10개, 20개로 늘어날 때 모든 서비스에 똑같은 코드를 중복해서 작성하는 것은 비효율적이다.
게이트웨이는 이런 '공통 로직'을 한 곳에서 처리해준다.
- 인증 및 인가 (Authentication & Authorization): 클라이언트가 보낸 JWT 토큰의 유효성을 개별 백엔드 서비스가 아닌 게이트웨이의 Global Filter에서 단 한 번만 검증합니다. 검증이 완료된 안전한 요청만 백엔드로 넘기면서, 요청 헤더에 X-User-Id 같은 식별자를 끼워 넣어주면 백엔드 개발이 훨씬 수월해집니다.
- 전역 CORS 설정: 프론트엔드(React, Vue 등)와 통신할 때 발생하는 CORS 에러를 각 서비스마다 설정할 필요 없이 게이트웨이 단에서 한 번에 해결할 수 있습니다.
- 공통 로깅 (Centralized Logging): 모든 요청의 진입점과 이탈점을 기록하여, 어떤 API가 얼마나 자주 호출되는지, 응답 시간은 얼마나 걸리는지 한 곳에서 모니터링할 수 있습니다.
2. 서비스 장애 전파 방지 (Resilience & Fault Tolerance)
하나의 서비스가 죽었다고 해서 전체 시스템이 마비되는 이른바 '연쇄 장애'를 막는 것이 중요합니다.
- 서킷 브레이커 (Circuit Breaker): 특정 서비스(예: 상품 서비스)에 장애가 생겨 응답이 지연될 때, 게이트웨이가 이를 감지하고 해당 서비스로 가는 길을 일시적으로 차단(Open)합니다. 대신 "현재 상품 정보를 불러올 수 없습니다"라는 기본값(Fallback)을 빠르게 반환하여 다른 정상적인 서비스(예: 주문 서비스)까지 느려지는 것을 방지합니다. (주로 Resilience4j를 연동하여 사용합니다.)
- 처리율 제한 (Rate Limiting): 특정 클라이언트나 IP에서 비정상적으로 엄청난 양의 요청을 보낼 때, 시스템을 보호하기 위해 초당 요청 수를 제한합니다.
- Redis와 결합하여 "1분에 100회 초과 시 429 Too Many Requests 에러 반환"과 같은 방어 로직을 게이트웨이에 구현합니다.
3. 스프링 클라우드 게이트웨이(SCG)와 비동기 프로그래밍
개발자들이 SCG를 처음 다룰 때 가장 많이 겪는 트러블슈팅 포인트입니다.
- Spring WebFlux 기반 (논블로킹 I/O): 기존의 익숙한 Spring MVC(Tomcat) 기반이 아니라, 비동기 처리에 특화된 WebFlux(Netty) 기반으로 동작합니다. 따라서 필터를 작성할 때 Thread.sleep() 같은 동기식(Blocking) 코드를 절대 사용하면 안 됩니다.
- 리액티브 타입 (Mono / Flux): 게이트웨이 필터 체인을 다루기 위해서는 Mono(0 또는 1개의 결과)와 Flux(0~N개의 결과)라는 리액티브 프로그래밍 개념에 익숙해져야 합니다. 데이터베이스를 조회하거나 외부 API를 호출하는 로직을 필터에 넣어야 한다면 반드시 비동기 방식을 사용해야 성능 저하를 막을 수 있습니다.
4. 분산 추적 (Distributed Tracing)
마이크로서비스 환경에서 가장 큰 고통은 "대체 어느 서비스에서 에러가 났고, 왜 느려졌는가?"를 찾는 것입니다.
- Trace ID와 Span ID: 사용자의 요청이 게이트웨이에 들어오는 순간, 게이트웨이는 고유한 아이디(Trace ID)를 생성하여 헤더에 심어줍니다. 이 요청이 A 서비스, B 서비스를 거칠 때마다 이 아이디를 함께 넘겨받기 때문에, 나중에 로그를 검색할 때 아이디 하나만 검색하면 전체 요청 흐름을 한눈에 추적할 수 있습니다. (Micrometer Tracing, Zipkin 등의 툴과 함께 사용)
🎯 면접 질문 대비 (Interview Q&A)
Q1. MSA 환경에서 API Gateway가 필요한 이유는 무엇인가요?
A. 클라이언트와 마이크로서비스 간의 '단일 진입점' 역할을 수행하기 때문입니다. Gateway가 없다면 클라이언트는 수많은 백엔드 서비스의 주소를 모두 알아야 합니다. Gateway를 도입함으로써 라우팅, 로드 밸런싱, 중앙 집중식 보안(인증/인가), 공통 로깅 등을 효율적으로 처리할 수 있습니다.
Q2. Spring Cloud Gateway에서 Pre Filter와 Post Filter를 구현할 때 코드상의 차이점은 무엇인가요?
A. 두 필터 모두 GatewayFilterChain을 사용하지만 실행 시점 처리 방식이 다릅니다.
Pre 필터는 라우팅 이전에 실행되므로 선행 작업 후 chain.filter(exchange)를 반환하여 다음 체인으로 요청을 넘기면 됩니다. 반면 Post 필터는 백엔드 응답이 돌아온 후 실행되어야 하므로 chain.filter(exchange).then(Mono.fromRunnable(...))를 호출하여 응답 완료 이후의 비동기 콜백 로직을 정의해야 합니다.
Q3. 기존 Spring Boot 2에서 사용되던 Zuul과 현재의 Spring Cloud Gateway의 차이를 알고 있나요?
A. 역할 자체는 API 게이트웨이로 동일합니다.
실제 기술적으로는 통신 방식의 차이(Zuul은 동기식, Spring Cloud Gateway는 비동기 논블로킹 방식)가 존재합니다.
현업에서는 기존 레거시 시스템이 부트 2 기반일 경우 Zuul이 적용되어 있을 수 있음을 인지하고 대응할 수 있어야 합니다.
'MSA' 카테고리의 다른 글
| 로깅(Observability) 완전 정리장애가 나면 어디부터 봐야 할까? (0) | 2026.05.15 |
|---|---|
| OpenFeign 공식 문서 ,선언적 HTTP 클라이언트의 모든 것 (0) | 2026.05.15 |
| 서킷브레이커 (1) | 2026.04.14 |
| 로드밸런싱 (0) | 2026.04.14 |
| 서비스 디스커버리 (0) | 2026.04.13 |
