게이트웨이와 리버스 프록시
핵심 질문
높은 동시성의 인터넷 아키텍처에서 트래픽을 안전하고 효율적으로 올바른 서비스로 전달하려면 어떻게 해야 할까? 리버스 프록시는 "트래픽을 어떻게 분배할 것인가"를 해결하고, API 게이트웨이는 "요청을 어떻게 처리할 것인가"를 해결합니다. 이 글은 실제 사례(프론트 데스크, 보안 시스템, 스마트 라우팅)를 통해 게이트웨이의 설계 철학과 엔지니어링 실무를 깊이 있게 이해합니다.
1. 왜 "게이트웨이"가 필요한가?
1.1 실제 사례로 시작: 한 이커머스의 아키텍처 진화
한 이커머스 플랫폼이 비즈니스가 빠르게 성장하면서 심각한 아키텍처 문제에 직면했습니다:
상황 재현:
1단계: 서비스 직접 노출
클라이언트 → 사용자 서비스, 주문 서비스, 결제 서비스에 직접 호출
↓
문제 1: 서비스 IP가 노출되어 보안 위험
문제 2: 인증, 속도 제한을 통합해서 처리 불가
문제 3: 새로운 서비스 추가 시 클라이언트 설정 수정 필요직접 노출의 치명적 문제
- 보안 위험: 모든 서비스 IP가 노출되어 공격에 취약
- 기능 중복: 각 서비스마다 인증, 속도 제한, 로깅을 구현해야 함
- 확장 어려움: 새로운 서비스를 추가하면 모든 클라이언트를 수정해야 함
- 프로토콜 혼란: HTTP를 쓰는 곳도 있고, gRPC를 쓰는 곳도 있어 클라이언트가 모두 적응해야 함
개선된 아키텍처(게이트웨이 도입):
클라이언트 → API 게이트웨이(Nginx/Kong) → 내부 서비스
↓
통합 인증, 속도 제한, 라우팅
↓
클라이언트는 게이트웨이 주소만 알면 됨1.2 게이트웨이의 생활 속 비유
프론트 데스크
대기업에 방문한다고 상상해 보세요:
- 프론트 데스크가 없는 경우: 방문객이 각 부서에 직접 찾아가고, 위치를 몰라 회사가 혼란
- 프론트 데스크가 있는 경우: 방문객이 먼저 프론트에 오고, 프론트가 용건을 확인한 후 해당 부서로 안내
API 게이트웨이가 시스템의 "프론트 데스크"입니다:
- 리버스 프록시: 프론트 데스크, 방문객을 올바른 부서로 안내
- API 게이트웨이: 스마트 프론트 데스크, 방문객의 신원 확인(인증), 접속 인원 제한(속도 제한)도 가능
- 客户端无感知,只需要访问域名
- 隐藏真实服务器架构,统一对外接口
- 提供负载均衡、安全防护、SSL卸载等功能
- 典型代表:Nginx、HAProxy、AWS ELB
- 网站需要承载高并发流量(负载均衡)
- 统一HTTPS证书管理(SSL卸载)
- 防护DDoS攻击和SQL注入
- 灰度发布、A/B测试、蓝绿部署
"反向代理 = 代理服务器" —— 客户端不知道真实服务器,只知道域名
2. 리버스 프록시란 무엇인가?
2.1 포워드 프록시 vs 리버스 프록시
용어 설명
포워드 프록시(Forward Proxy):
- 클라이언트 측에 배포
- 클라이언트를 대신하여 외부 리소스에 접근
- 대표적 응용: VPN, 프록시 도구
- 예시: 회사 네트워크에서 프록시를 통해 외부망에 접근
리버스 프록시(Reverse Proxy):
- 서버 측에 배포
- 클라이언트 요청을 받아 내부 서비스에 전달
- 클라이언트는 프록시만 알고, 실제 서버는 모름
- 예시: Nginx, HAProxy
비교 표:
| 차원 | 포워드 프록시 | 리버스 프록시 |
|---|---|---|
| 배포 위치 | 클라이언트 측 | 서버 측 |
| 서비스 대상 | 클라이언트 | 서버 |
| 대표적 응용 | VPN, 프록시 | 로드 밸런싱, 게이트웨이 |
| 투명성 | 서버가 프록시 IP를 봄 | 클라이언트가 프록시 IP를 봄 |
| 목적 | 실제 클라이언트 숨기기, 접속 가속 | 실제 서버 숨기기, 로드 밸런싱 |
2.2 리버스 프록시의 핵심 가치
가치 1: 로드 밸런싱
트래픽을 여러 백엔드 서버로 분산하여 단일 서버 과부하 방지.
클라이언트
↓
Nginx(리버스 프록시)
↓
┌─────────┬─────────┬─────────┐
│ 서버 1 │ 서버 2 │ 서버 3 │
└─────────┴─────────┴─────────┘가치 2: 보안 보호
실제 서버 IP를 숨겨 직접 공격을 방지하고, 프록시 계층에서 통합 보안 보호.
클라이언트 → Nginx의 IP만 볼 수 있음
실제 서버 → 내부망에만 있어 외부에서 직접 접근 불가가치 3: SSL 종료
프록시 계층에서 HTTPS 암호화/복호화를 처리하고, 백엔드 서비스는 HTTP를 사용하여 백엔드 컴퓨팅 오버헤드를 감소.
HTTPS 클라이언트 → Nginx(암호화/복호화) → HTTP 백엔드 서비스
↑
SSL 종료점3. Nginx: 왜 수백만 동시 접속을 감당할 수 있는가?
3.1 Master-Worker 프로세스 모델
Nginx는 다중 프로세스 아키텍처를 채택하며, 다중 스레드가 아닙니다:
Master 프로세스(관리자):
- 설정 파일을 읽고 검증
- Worker 프로세스 관리(시작, 중지, 재로딩)
- 구체적인 요청을 처리하지 않음
Worker 프로세스(작업자):
- 실제 HTTP 요청 처리
- 각 Worker는 독립적인 프로세스로 서로 격리됨
- 수량은 보통 CPU 코어 수로 설정하여 컨텍스트 전환 오버헤드 방지
장점
- 격리성 우수: 하나의 Worker가 충돌해도 다른 Worker에 영향 없음
- 멀티코어 활용: 각 Worker가 독립적으로 실행
- 다중 스레드 복잡성 회피: 락, 경쟁 등의 문제를 처리할 필요 없음
3.2 이벤트 구동 + 비동기 논블로킹
이것이 Nginx의 고성능 핵심 비밀입니다:
전통적 Apache(다중 프로세스/스레드 모델):
- 하나의 연결 = 하나의 프로세스/스레드
- 동시성 수는 시스템 프로세스/스레드 수에 의해 제한
- 대량의 연결 시 프로세스 전환 오버헤드가 막대
Nginx(이벤트 구동 모델):
- epoll(Linux)/kqueue(macOS) 등 고효율 I/O 멀티플렉싱 메커니즘 사용
- 하나의 Worker 프로세스가 수만 개의 연결을 동시에 처리
- 연결에 데이터가 없을 때는 CPU를 점유하지 않고, 새로운 데이터가 도착하면 이벤트 알림으로 깨어남
太多了上下文切换开销大,太少了无法利用多核性能。
4. API 게이트웨이란 무엇인가?
4.1 왜 API 게이트웨이가 필요한가?
| 功能需求 | 没有网关 (直接访问) | 有 API 网关 |
|---|---|---|
| 身份认证 | 每个服务都要写一遍登录校验 | ✅ 统一在网关层校验 JWT |
| 限流保护 | 每个服务自己实现限流 | ✅ 网关统一限流,保护后端 |
| 协议转换 | HTTP、gRPC、WebSocket各自处理 | ✅ 网关统一对外暴露 HTTP |
| 灰度发布 | 需要改负载均衡器配置 | ✅ 网关层按 Header 路由 |
4.2 API 게이트웨이의 핵심 기능
| 기능 | 설명 | 대표적 시나리오 |
|---|---|---|
| 라우팅 전달 | URL, Header 등 규칙에 따라 요청을 다른 서비스로 전달 | /api/users → 사용자 서비스,/api/orders → 주문 서비스 |
| 로드 밸런싱 | 같은 서비스에 여러 인스턴스가 있을 때 트래픽 분배 | 사용자 서비스에 3대의 인스턴스가 있을 때 라운드 로빈으로 요청 분배 |
| 인증 및 권한 | JWT, OAuth Token을 통합 검증 | 로그인하지 않은 사용자는 /api/admin에 접속 불가 |
| 속도 제한 및 서킷 브레이커 | 트래픽 상한선을 제어하여 서비스 과부하 방지 | 초당 최대 1000요청, 초과 시 429 반환 |
| 프로토콜 변환 | 외부는 HTTP, 내부는 gRPC로 변환 가능 | 클라이언트는 HTTP, 게이트웨이에서 gRPC로 변환하여 내부 서비스 호출 |
| 카나리아 배포 | Header나 비율에 따라 일부 트래픽을 새 버전으로 유도 | 5%의 사용자가 새 버전을 체험, 95%는 구 버전 사용 |
| 로그 모니터링 | 요청 로그를 통합 기록하여 분석과 트러블슈팅에 활용 | 각 요청의 소요 시간, 상태 코드, 반환 크기 기록 |
5. 게이트웨이 실전: 완전한 게이트웨이 아키텍처는 어떻게 구축하는가?
5.1 완전한 아키텍처 다이어그램
┌───────────────────────────────────────────────────────────────────────┐
│ 클라이언트(브라우저/APP) │
└───────────────────────────┬─────────────────────────────────────────┘
│ HTTPS
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 외부 계층: CDN + WAF │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CDN(콘텐츠 전송 네트워크) │ │
│ │ - 정적 리소스 캐싱(이미지, CSS, JS) │ │
│ │ - 근거리 접속, 지연 감소 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ WAF(웹 애플리케이션 방화벽) │ │
│ │ - SQL 인젝션, XSS 공격 방어 │ │
│ │ - 악성 봇, 크롤러 차단 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 중간 계층: API 게이트웨이(Nginx/Kong) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 1계층: SSL 종료 + 보안 보호 │ │
│ │ - HTTPS / TLS 1.3 │ │
│ │ - HSTS, 보안 응답 헤더 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 2계층: 인증 및 권한 │ │
│ │ - JWT Token 검증 │ │
│ │ - OAuth 2.0 / SSO 통합 │ │
│ │ - API Key 관리 │ │
│ │ - 권한 검증(RBAC) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 3계층: 트래픽 제어 │ │
│ │ - 속도 제한 - 토큰 버킷/리키 버킷 알고리즘 │ │
│ │ - 서킷 브레이커 - 장애 확산 방지 │ │
│ │ - 성능 저하 - 서비스 이용 불가 시 대체方案 │ │
│ │ - 카나리아 배포 - 비율에 따라 트래픽 할당 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 4계층: 라우팅과 로드 밸런싱 │ │
│ │ - 경로 기반 라우팅(Path-based Routing) │ │
│ │ - 도메인 기반 라우팅(Host-based Routing) │ │
│ │ - Header 기반 라우팅(Header-based Routing) │ │
│ │ - 로드 밸런싱 알고리즘(라운드 로빈/가중치/최소 연결/IP 해시) │ │
│ │ - 서비스 디스커버리(Service Discovery) 통합 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 내부 계층: 마이크로서비스 클러스터 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 사용자 서비스 │ │ 주문 서비스 │ │ 상품 서비스 │ │ 결제 서비스 │ │
│ │ User Svc │ │ Order Svc │ │ Product Svc │ │ Payment Svc │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴────────────────┘ │
│ │ │
│ 서비스 디스커버리 및 설정 센터(Consul / etcd) │
└───────────────────────────────────────────────────────────────────────┘6. 게이트웨이 보안: 시스템 현관문을 어떻게 지킬 것인가?
6.1 인증과 권한 부여
| 对比维度 | Session + Cookie | JWT | OAuth2.0 |
|---|---|---|---|
| 存储位置 | 服务端存储 Session,客户端存 Cookie | 客户端存储 Token,服务端无状态 | 授权服务器存储,客户端存 Access Token |
| 扩展性 | ❌ 需要共享 Session,扩展复杂 | ✅ 无状态,易于水平扩展 | ✅ 分布式架构,支持大规模系统 |
| 安全性 | ⚠️ Cookie 可能被窃取,需要 CSRF 防护 | ⚠️ Token 泄露风险,需 HTTPS + 短期有效 | ✅ 行业最佳实践,支持多种安全机制 |
| 实现复杂度 | 🟢 简单,开箱即用 | 🟡 中等,需要 Token 管理 | 🔴 复杂,需要授权服务器 |
| 适用场景 | 传统 Web 应用、后台管理系统 | SPA、移动端 API、微服务 | 第三方登录、开放平台、SSO |
핵심 사상
인증은 게이트웨이에서, 권한 부여는 서비스에서:
- 인증: 당신은 누구인가?(Token 검증, 사용자 신원 획득)
- 권한 부여: 당신은 무엇을 할 수 있는가?(사용자 역할에 따라 권한 판단)
회사 프론트 데스크와 같습니다: 프론트에서 당신의 신원(신분증)을 확인하지만, 구체적인 권한은 각 부서에서 판단합니다.
6.2 HTTPS와 SSL 종료
openssl genrsa -out private.key 2048openssl req -new -key private.key -out csr.pem# 添加 DNS TXT 记录 或 上传验证文件到 /.well-known/# 下载 certificate.crt 和 chain.crtnginx -t && systemctl reload nginx7. 속도 제한과 서킷 브레이커: 시스템이 "트래픽 홍수"에 쓸려가는 것을 어떻게 방지할 것인가?
7.1 속도 제한 알고리즘 비교
| 알고리즘 | 핵심 사상 | 버스트 트래픽 | 적용 시나리오 | 구현 복잡도 |
|---|---|---|---|---|
| 토큰 버킷 | 버킷에 토큰을 담고, 토큰이 있어야 통과 | 어느 정도의 버스트 허용 | API 속도 제한, 대역폭 제어 | 중간 |
| 리키 버킷 | 요청이 버킷에 들어오고, 일정한 속도로 흘러나가 처리 | 강제 평탄화, 버스트는 캐싱되거나 거부됨 | 엄격한 일정한 속도 처리가 필요한 시나리오 | 중간 |
| 슬라이딩 윈도우 | 시간 윈도우 내의 요청 수를 통계 | 윈도우별로 엄격히 계산, 초과 시 모두 거부 | 정확한 통계(예: "1분 내 최대 100회") | 높음 |
| 维度 | 令牌桶 (Token Bucket) | 漏桶 (Leaky Bucket) | 滑动窗口 (Sliding Window) |
|---|---|---|---|
| 核心思想 | 桶里装令牌,有令牌才能通过 | 请求进桶,匀速流出处理 | 统计时间窗口内的请求数 |
| 突发流量 | ✅ 允许一定程度的突发(桶里有令牌) | ❌ 强制平滑,突发会被缓存或拒绝 | ❌ 严格按窗口计数,超出一律拒绝 |
| 适用场景 | API 限流、带宽控制(允许突发) | 需要严格匀速处理的场景(如消息队列) | 精确统计(如"1分钟内最多100次") |
| 实现复杂度 | 中等 | 中等 | 较高(需要记录每个时间窗口的请求) |
| Nginx 配置 | limit_req_zone (漏桶) | limit_req_zone (漏桶) | 需第三方模块或 Lua |
# 定义限流区域
# $binary_remote_addr: 按 IP 限流
# zone=mylimit:10m: 区域名称和大小
# rate=10r/s: 每秒最多10个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
listen 80;
server_name api.example.com;
location / {
# 应用限流
# burst=20: 桶容量,允许突发20个请求
# nodelay: 不延迟处理突发请求
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://backend;
}
}- limit_req_zone: 在 http 块中定义限流区域
- $binary_remote_addr: 使用二进制 IP 地址作为限流键(省内存)
- zone=mylimit:10m: 区域名称 mylimit,分配 10MB 内存
- rate=10r/s: 每秒允许 10 个请求(漏桶算法)
- burst=20: 桶的容量为 20,允许一定程度的突发流量
- nodelay: 不延迟处理突发请求(立即处理或拒绝)
7.2 서킷 브레이커: 장애 확산 방지
서킷 브레이커의 작동 원리:
- 닫힌 상태: 정상적으로 요청을 전달하면서 오류율을 통계
- 열린 상태: 오류율이 임계값을 초과하면 서킷 브레이커가 열리고, 직접 에러를 반환하며 더 이상 요청을 전달하지 않음
- 반열림 상태: 일정 시간이 지난 후 소량의 요청을 통과시켜 시도하고, 성공하면 서킷 브레이커를 닫음
핵심 사상
서킷 브레이커는 전기 퓨즈와 같습니다: 전류가 과도하면 퓨즈가 자동으로 끊어져 전체 회로가 타는 것을 보호합니다.
마찬가지로 백엔드 서비스에 대량의 오류가 발생하면 서킷 브레이커가 "트립"되어 빠른 실패를 통해 장애 확산을 방지합니다.
8. 요약: 게이트웨이 설계의 핵심 사고
8.1 핵심 원칙 복습
| 원칙 | 의미 | 실무 포인트 |
|---|---|---|
| 라우팅 | 요청을 올바른 곳으로 전달 | 경로 라우팅, 도메인 라우팅, Header 라우팅 |
| 로드 밸런싱 | 트래픽을 여러 서버로 분배 | 라운드 로빈, 가중치, 최소 연결, IP 해시 |
| 보안 | 시스템 현관문 수호 | 인증 권한 부여, HTTPS, WAF |
| 속도 제한 | 트래픽에 쓸려가는 것 방지 | 토큰 버킷, 리키 버킷, 슬라이딩 윈도우 |
| 서킷 브레이커 | 장애 확산 방지 | 빠른 실패, 저하 방안 |
| 관측 가능성 | 모니터링과 트러블슈팅 | 로그, 지표, 분산 추적 |
8.2 기술 선택 제안
선택 의사결정 트리
게이트웨이 선택:
│
├─ 리버스 프록시, 로드 밸런싱만 필요한가?
│ ├─ 예 → Nginx(1순위)
│ └─ 아니오 → 계속
│
├─ 풍부한 플러그인 생태계가 필요한가?
│ ├─ 예 → Kong(Nginx 기반)
│ └─ 아니오 → 계속
│
├─ Spring Cloud 풀패키지인가?
│ ├─ 예 → Spring Cloud Gateway
│ └─ 아니오 → Nginx9. 용어 빠른 참조표
| 용어 | 영문 | 설명 |
|---|---|---|
| 리버스 프록시 | Reverse Proxy | 서버 측에 배포되어 클라이언트 요청을 받아 내부 서비스에 전달하는 프록시 서비스. 클라이언트는 리버스 프록시의 존재만 알고 실제 서버 주소는 모름. |
| 포워드 프록시 | Forward Proxy | 클라이언트 측에 배포되어 클라이언트를 대신하여 외부 리소스에 접근하는 프록시 서비스. 서버는 프록시의 IP를 보며 실제 클라이언트를 모름. 전형적 응용: VPN, 프록시 도구. |
| API 게이트웨이 | API Gateway | 클라이언트와 백엔드 서비스 사이의 중간 계층으로, 라우팅, 인증, 속도 제한, 로깅 등의 기능을 제공하며 마이크로서비스 아키텍처의 "통일된 대문". |
| 로드 밸런싱 | Load Balancing | 요청 트래픽을 여러 서버에 분배하여 단일 서버의 과부하를 방지하고 시스템 가용성과 성능을 향상. |
| SSL 종료 | SSL Termination | 게이트웨이 계층에서 HTTPS 암호화/복호화를 처리하고 백엔드 서비스는 HTTP를 사용하여 백엔드 컴퓨팅 오버헤드를 감소하고 인증서 관리를 간소화. |
| 속도 제한 | Rate Limiting | 단위 시간 내의 요청 수를 제한하여 시스템이 버스트 트래픽에 압도되는 것을 방지. 일반적 알고리즘: 토큰 버킷, 리키 버킷, 슬라이딩 윈도우. |
| 서킷 브레이커 | Circuit Breaking | 의존 서비스에 장애가 발생하면 자동으로 호출을 차단하여 장애 확산을 방지하고 저하 방안을 제공. |
| 세션 지속성 | Session Persistence | 동일한 클라이언트의 요청이 항상 같은 백엔드 서버로 라우팅되도록 보장하여 세션 상태를 유지해야 하는 시나리오에 사용. |
| 헬스 체크 | Health Check | 백엔드 서비스의 건강 상태를 정기적으로 확인하여 장애 노드를 자동으로 제외하고 트래픽이 건강한 서비스 인스턴스에만 전송되도록 보장. |
| 카나리아 배포 | Canary Release | 소량의 트래픽을 새 버전으로 유도하고 안정성을 검증한 후 점진적으로 비율을 확대하여 배포 위험을 감소. |
| WAF | Web Application Firewall | 웹 애플리케이션 방화벽으로 SQL 인젝션, XSS, CC 공격 등 웹 보안 위협을 방어. |
| CDN | Content Delivery Network | 콘텐츠 전송 네트워크로 전 세계에 엣지 노드를 배포하여 정적 리소스 접속을 가속화. |