Reverse Proxy Giải Thích Chi Tiết

Mọi web application trên production đều nằm sau một reverse proxy. Có thể bạn không nhận ra, nhưng nếu đã deploy lên Vercel, AWS, hay bất kỳ cloud provider nào — có một reverse proxy giữa users và code của bạn.
Trong bài Load Balancing, chúng ta đã nói về việc phân phối traffic qua nhiều servers. Reverse proxy làm nhiều hơn thế — nó là cánh cửa chính vào toàn bộ backend, xử lý SSL, caching, security, routing, và đương nhiên cả load balancing nữa.
Thời gian: 1-2 giờ
Điều kiện: Hiểu cơ bản về HTTP và kiến trúc client-server
Những Gì Bạn Sẽ Học
✅ Reverse proxy là gì và khác forward proxy như thế nào
✅ Cách reverse proxy hoạt động — request flow đầy đủ
✅ SSL/TLS termination — chuyển việc mã hóa ra khỏi application
✅ Caching — trả response mà không cần đụng backend
✅ Security benefits — ẩn servers, chặn attacks, rate limit
✅ Load balancing — phân phối traffic với reverse proxy
✅ WebSocket và gRPC proxying — hỗ trợ real-time protocols
✅ Setup thực tế — cấu hình Nginx, Traefik, và Caddy
1. Reverse Proxy Là Gì?
Reverse proxy nằm giữa clients và backend servers. Clients không bao giờ nói chuyện trực tiếp với servers — họ nói với proxy, và proxy forward requests tới đúng server.
Điểm mấu chốt: clients không biết server nào xử lý request. Họ chỉ thấy IP address của reverse proxy. Concept đơn giản này enable mọi thứ khác — SSL termination, caching, load balancing, security.
Nó Thực Sự Làm Gì
Khi request đến reverse proxy:
- Nhận HTTP request từ client
- Kiểm tra request (URL path, headers, method)
- Quyết định backend server nào xử lý
- Forward request tới server đó
- Nhận response từ backend
- Trả response cho client
Client nghĩ mình đang nói chuyện với một server. Thực tế, có thể có hàng chục servers phía sau proxy.
2. Forward Proxy vs Reverse Proxy
Hai khái niệm này hay bị nhầm. Chúng nằm ở hai phía đối lập của connection.
| Khía Cạnh | Forward Proxy | Reverse Proxy |
|---|---|---|
| Bảo vệ | Clients | Servers |
| Ai dùng | Phía client (mạng công ty, VPN) | Phía server (web infrastructure) |
| Client biết không | Có (cấu hình trong browser/OS) | Không (transparent) |
| Server biết không | Không (thấy IP của proxy) | Có (cấu hình để nhận từ proxy) |
| Mục đích chính | Access control, anonymity, caching | Security, performance, routing |
| Ví dụ | Squid, corporate firewalls, VPN | Nginx, Traefik, Cloudflare |
Forward proxy: Proxy của công ty bạn filter web traffic. Bạn cấu hình browser để dùng nó. Website không biết bạn đang sau proxy.
Reverse proxy: Nginx ngồi trước Node.js app. Users không biết nó tồn tại. Node.js app biết requests đến thông qua nó.
3. Tại Sao Dùng Reverse Proxy?
Bạn có thể expose application trực tiếp ra internet. Đây là lý do không nên:
Security
Application servers ẩn trên private network. Attackers không thể truy cập trực tiếp.
Không có reverse proxy:
Internet → App Server (public IP, exposed ports, vulnerable)
Có reverse proxy:
Internet → Reverse Proxy (public IP) → App Server (private network)Reverse proxy là gateway được hardened, build chuyên dụng. Application server thoải mái focus vào business logic mà không lo DDoS protection, rate limiting, hay IP filtering.
Performance
- SSL termination: Xử lý encryption ở proxy, không phải app
- Caching: Trả cached responses mà không đụng backend
- Compression: Gzip/Brotli responses trước khi gửi cho clients
- Connection pooling: Tái sử dụng backend connections thay vì tạo mới
- Static file serving: Để proxy serve images, CSS, JS trực tiếp
Flexibility
- Zero-downtime deploys: Swap backend servers mà không drop connections
- A/B testing: Route traffic tới các app versions khác nhau
- API gateway: Route
/api/*tới một service,/web/*tới service khác - Protocol translation: Nhận HTTP/2 từ clients, nói HTTP/1.1 với backends
4. Cách Reverse Proxy Hoạt Động
Hãy trace một request hoàn chỉnh qua reverse proxy:
Hành Trình Của Request
Bước 1 — SSL Termination: Proxy decrypt HTTPS request. Backend servers nhận plain HTTP trên private network.
Bước 2 — Cache Check: Nếu response đã được cache và còn fresh, trả về ngay. Backend không bao giờ thấy request này.
Bước 3 — Rate Limiting: Kiểm tra xem client IP đã vượt quá request limits chưa. Nếu rồi, trả 429 Too Many Requests.
Bước 4 — Backend Selection: Chọn backend server (round robin, least connections, URL-based routing).
Bước 5 — Cache Storage: Nếu response từ backend có Cache-Control headers, lưu lại cho future requests.
Bước 6 — Compression: Nén response body bằng gzip hoặc Brotli trước khi gửi cho client.
Headers Được Proxy Thêm Vào
Reverse proxies thêm headers để backends biết thông tin request gốc:
X-Forwarded-For: 203.0.113.50 # IP thật của client
X-Forwarded-Proto: https # Protocol gốc
X-Forwarded-Host: example.com # Hostname gốc
X-Real-IP: 203.0.113.50 # Client IP (Nginx-specific)
X-Request-ID: abc-123-def # Request identifier duy nhấtKhông có headers này, backend sẽ thấy IP của proxy thay vì client IP — phá vỡ logging, rate limiting, và geolocation.
5. SSL/TLS Termination
SSL termination là lý do phổ biến nhất để dùng reverse proxy. Nó chuyển việc encryption ra khỏi application.
Tại Sao Terminate Ở Proxy?
| Không Có Proxy | Có Proxy |
|---|---|
| Mỗi app server cần SSL certificates | Một certificate trên proxy |
| App xử lý TLS handshakes (tốn CPU) | Proxy xử lý toàn bộ TLS |
| Renew certificate trên mỗi server | Renew một lần, một chỗ |
| App frameworks cần SSL configuration | App chạy plain HTTP |
| Mixed protocols phức tạp hơn | HTTP nội bộ sạch sẽ |
Nginx SSL Termination
server {
listen 443 ssl http2;
server_name example.com;
# SSL certificates
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Modern TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS (bảo browsers luôn dùng HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;
# Proxy tới backend (plain HTTP)
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Redirect HTTP sang HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}Các SSL Modes
SSL Termination:
SSL Passthrough:
SSL Re-encryption:
| Mode | Client → Proxy | Proxy → Backend | Use Case |
|---|---|---|---|
| Termination | HTTPS | HTTP | Phổ biến nhất. Backend trên private network |
| Passthrough | HTTPS | HTTPS (cùng connection) | Proxy không inspect traffic. End-to-end encryption |
| Re-encryption | HTTPS | HTTPS (connection mới) | Compliance requirements. Proxy inspect + re-encrypt |
Với hầu hết applications, SSL termination là lựa chọn đúng. Backend chạy trên private network nơi HTTP là đủ.
6. Caching
Reverse proxy có thể cache responses và serve mà không cần đụng backend. Đây là performance win lớn nhất cho read-heavy applications.
Cách Hoạt Động
Cấu Hình Nginx Caching
# Define cache zone (10MB metadata, 1GB storage, 60 phút hết hạn)
proxy_cache_path /var/cache/nginx levels=1:2
keys_zone=app_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
server {
listen 443 ssl http2;
server_name example.com;
location /api/ {
proxy_pass http://backend;
# Bật caching
proxy_cache app_cache;
proxy_cache_valid 200 10m; # Cache response 200 trong 10 phút
proxy_cache_valid 404 1m; # Cache response 404 trong 1 phút
proxy_cache_use_stale error timeout updating; # Serve stale khi error
proxy_cache_lock on; # Chỉ 1 request tới backend cho cùng URL
# Cache key (gì tạo nên mỗi cached entry duy nhất)
proxy_cache_key "$scheme$request_method$host$request_uri";
# Thêm cache status header để debug
add_header X-Cache-Status $upstream_cache_status;
}
# Không cache POST, PUT, DELETE
location /api/ {
if ($request_method != GET) {
set $no_cache 1;
}
proxy_cache_bypass $no_cache;
proxy_no_cache $no_cache;
}
# Cache static assets mạnh tay
location /static/ {
proxy_pass http://backend;
proxy_cache app_cache;
proxy_cache_valid 200 7d; # 7 ngày cho static files
add_header Cache-Control "public, max-age=604800";
}
}Cache Status Headers
Header X-Cache-Status cho biết chuyện gì xảy ra:
| Status | Ý Nghĩa |
|---|---|
HIT | Serve từ cache |
MISS | Không có trong cache, forward tới backend |
EXPIRED | Có trong cache nhưng hết hạn, fetch lại |
STALE | Cache hết hạn nhưng serve stale (backend đang down) |
BYPASS | Cache bị bypass (POST, cookie-based, v.v.) |
UPDATING | Serve stale trong khi update ở background |
Nên Cache Gì, Không Nên Cache Gì
| Cache | Không Cache |
|---|---|
API responses có Cache-Control headers | User-specific data (profile, cart, settings) |
| Static assets (CSS, JS, images, fonts) | Responses có Set-Cookie |
| Public content (blog posts, product listings) | POST/PUT/DELETE requests |
| Search results (với short TTL) | Real-time data (stock prices, chat) |
| Third-party API responses | Authenticated API responses |
7. Load Balancing với Reverse Proxy
Hầu hết reverse proxies đi kèm load balancing. Chúng ta đã cover algorithms chi tiết trong bài Load Balancing — đây là setup thực tế.
Nginx Load Balancing
# Define backend server group
upstream api_servers {
least_conn; # Dùng least connections algorithm
server 10.0.1.101:3000 weight=3; # Server mạnh hơn nhận nhiều traffic hơn
server 10.0.1.102:3000 weight=2;
server 10.0.1.103:3000 weight=1;
server 10.0.1.104:3000 backup; # Chỉ dùng khi các server khác down
# Health checks (Nginx Plus)
# health_check interval=10 fails=3 passes=2;
}
server {
listen 443 ssl http2;
server_name api.example.com;
location / {
proxy_pass http://api_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Timeouts
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 10s;
# Retry on failure
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;
}
}Path-Based Routing
Route các paths khác nhau tới các backend services khác nhau:
upstream web_app {
server 10.0.1.101:3000;
server 10.0.1.102:3000;
}
upstream api_service {
server 10.0.2.101:8080;
server 10.0.2.102:8080;
}
upstream admin_panel {
server 10.0.3.101:4000;
}
server {
listen 443 ssl http2;
server_name example.com;
# Frontend application
location / {
proxy_pass http://web_app;
}
# API service
location /api/ {
proxy_pass http://api_service;
}
# Admin panel (giới hạn bởi IP)
location /admin/ {
allow 10.0.0.0/8;
deny all;
proxy_pass http://admin_panel;
}
}Đây là API gateway pattern — một entry point duy nhất routing tới nhiều services dựa trên URL path, headers, hoặc các request attributes khác.
8. Security Benefits
Reverse proxy là tuyến phòng thủ đầu tiên. Đây là những gì nó làm được:
Ẩn Backend Servers
Expose trực tiếp:
Client → App Server tại 203.0.113.10:3000
(Attacker biết server IP, port, và technology)
Sau reverse proxy:
Client → Proxy tại 198.51.100.1:443
(Attacker chỉ thấy proxy. Backend trên private 10.x.x.x network)Proxy chỉ expose ports 80 và 443. Application servers vô hình với internet.
Rate Limiting
# Define rate limit zone (10MB shared memory, 10 requests/giây mỗi IP)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
server {
# API endpoints — 10 req/s với burst 20
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
# Login endpoint — strict 1 req/s
location /api/auth/login {
limit_req zone=login_limit burst=3;
limit_req_status 429;
proxy_pass http://backend;
}
}Request Filtering
Chặn suspicious requests trước khi chúng tới application:
server {
# Chặn known bad user agents
if ($http_user_agent ~* (bot|crawler|spider|scraper)) {
return 403;
}
# Chặn requests có SQL injection patterns
location /api/ {
if ($query_string ~* "(union|select|insert|update|delete|drop)") {
return 403;
}
proxy_pass http://backend;
}
# Chặn request bodies quá lớn (ngăn upload attacks)
client_max_body_size 10m;
# Ẩn server version
server_tokens off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}IP Allowlisting
# Admin endpoints chỉ truy cập được từ IPs cụ thể
location /admin/ {
allow 10.0.0.0/8; # Internal network
allow 192.168.1.0/24; # Office network
deny all; # Chặn tất cả
proxy_pass http://admin_backend;
}9. WebSocket và gRPC Proxying
Reverse proxies xử lý nhiều hơn HTTP. Applications hiện đại cần WebSocket và gRPC support.
WebSocket Proxying
WebSocket connections bắt đầu là HTTP rồi upgrade. Proxy cần handle việc upgrade này:
# WebSocket support
map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}
server {
listen 443 ssl http2;
server_name example.com;
# WebSocket endpoint
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
# Timeouts dài hơn cho WebSocket connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
# HTTP thông thường
location / {
proxy_pass http://web_backend;
}
}Settings quan trọng:
proxy_http_version 1.1— WebSocket yêu cầu HTTP/1.1UpgradevàConnectionheaders — bảo backend upgrade- Timeouts dài — WebSocket connections tồn tại lâu
gRPC Proxying
server {
listen 443 ssl http2;
server_name grpc.example.com;
location / {
grpc_pass grpc://grpc_backend;
grpc_set_header Host $host;
# Error handling
error_page 502 = /error502grpc;
}
location = /error502grpc {
internal;
default_type application/grpc;
add_header grpc-status 14;
add_header content-length 0;
return 204;
}
}10. Request/Response Manipulation
Reverse proxies có thể modify requests và responses khi chúng đi qua.
URL Rewriting
server {
# Rewrite /old-api/* thành /api/v2/*
location /old-api/ {
rewrite ^/old-api/(.*) /api/v2/$1 break;
proxy_pass http://backend;
}
# Strip prefix: /service-a/users → /users
location /service-a/ {
proxy_pass http://service_a_backend/; # Trailing slash strip prefix
}
# Add prefix: /users → /api/v1/users
location /users {
proxy_pass http://backend/api/v1/users;
}
}Header Manipulation
server {
location /api/ {
proxy_pass http://backend;
# Thêm headers vào request gửi tới backend
proxy_set_header X-Request-ID $request_id;
proxy_set_header X-Real-IP $remote_addr;
# Thêm headers vào response gửi cho client
add_header X-Served-By $hostname;
add_header X-Response-Time $request_time;
# Xóa sensitive headers từ backend response
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
}
}Response Compression
server {
# Bật gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
image/svg+xml;
# Không nén files đã nén
gzip_proxied any;
location / {
proxy_pass http://backend;
}
}11. Reverse Proxy Trong Microservices
Trong kiến trúc microservices, reverse proxy trở thành API gateway — single entry point cho tất cả client requests.
API Gateway Xử Lý Gì
| Trách Nhiệm | Ví Dụ |
|---|---|
| Routing | /api/users/* → User Service |
| Authentication | Validate JWT trước khi forward |
| Rate limiting | 100 req/phút mỗi API key |
| Request aggregation | Gom responses từ nhiều services |
| Protocol translation | Nhận REST, forward dạng gRPC |
| Circuit breaking | Ngừng forward tới failed services |
| Logging | Access logs tập trung |
Nginx Làm API Gateway
upstream auth_service {
server 10.0.1.101:3001;
}
upstream user_service {
server 10.0.2.101:3002;
server 10.0.2.102:3002;
}
upstream order_service {
server 10.0.3.101:3003;
server 10.0.3.102:3003;
server 10.0.3.103:3003;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# Auth subrequest — validate token trước khi forward
location = /auth/validate {
internal;
proxy_pass http://auth_service/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
# Protected endpoints — yêu cầu auth
location /api/users/ {
auth_request /auth/validate;
auth_request_set $auth_user $upstream_http_x_auth_user;
proxy_set_header X-Auth-User $auth_user;
proxy_pass http://user_service/;
}
location /api/orders/ {
auth_request /auth/validate;
auth_request_set $auth_user $upstream_http_x_auth_user;
proxy_set_header X-Auth-User $auth_user;
proxy_pass http://order_service/;
}
# Public endpoints — không cần auth
location /api/auth/ {
proxy_pass http://auth_service/;
}
}12. Các Reverse Proxy Solutions Phổ Biến
Nginx
Reverse proxy được dùng nhiều nhất. Xử lý hàng triệu concurrent connections với ít resources.
Phù hợp nhất cho: General-purpose reverse proxy, static file serving, SSL termination.
# Complete Nginx reverse proxy setup
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Security
server_tokens off;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Compression
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# Proxy tới backend
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
# Static files
location /static/ {
alias /var/www/static/;
expires 7d;
add_header Cache-Control "public, immutable";
}
}Traefik
Thiết kế cho containerized environments. Tự động phát hiện services từ Docker và Kubernetes.
Phù hợp nhất cho: Docker Compose, Kubernetes, dynamic service discovery.
# docker-compose.yml với Traefik
version: "3.8"
services:
traefik:
image: traefik:v3.0
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "[email protected]"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
api:
image: my-api:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=3000"
deploy:
replicas: 3
web:
image: my-web:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`example.com`)"
- "traefik.http.routers.web.tls.certresolver=letsencrypt"
- "traefik.http.services.web.loadbalancer.server.port=8080"
volumes:
letsencrypt:Siêu năng lực của Traefik: không cần config files cho routing. Thêm Docker labels vào services, Traefik tự động tạo routes, SSL certificates, và load balancing.
Caddy
Reverse proxy đơn giản nhất. Automatic HTTPS không cần cấu hình gì.
Phù hợp nhất cho: Deployments nhỏ đến trung bình khi simplicity quan trọng nhất.
# Caddyfile — đây là toàn bộ configuration
example.com {
reverse_proxy 127.0.0.1:3000
# Automatic HTTPS — Caddy xử lý certificates
# Automatic HTTP → HTTPS redirect
# Automatic certificate renewal
}
api.example.com {
reverse_proxy /api/users/* 10.0.1.101:3001 10.0.1.102:3001 {
lb_policy least_conn
health_uri /health
health_interval 10s
}
reverse_proxy /api/orders/* 10.0.2.101:3002
# Compression
encode gzip
# Rate limiting
rate_limit {
zone api {
key {remote_host}
events 100
window 1m
}
}
}So Sánh
| Feature | Nginx | Traefik | Caddy |
|---|---|---|---|
| Configuration | Config files | Labels/API | Caddyfile |
| Auto HTTPS | Manual (certbot) | Built-in | Built-in |
| Docker integration | Manual | Automatic | Plugin |
| Performance | Excellent | Good | Good |
| Learning curve | Moderate | Low (Docker) | Very low |
| Ecosystem | Huge | Growing | Growing |
| Phù hợp nhất | Production at scale | Containers | Simple deployments |
13. Performance Optimization
Connection Pooling
Không có connection pooling, mỗi request tạo TCP connection mới tới backend:
Client → Proxy → [TCP connection mới] → Backend → [đóng] → Proxy → Client
Client → Proxy → [TCP connection mới] → Backend → [đóng] → Proxy → ClientVới keepalive connections:
Client → Proxy → [tái sử dụng connection] → Backend → Proxy → Client
Client → Proxy → [tái sử dụng connection] → Backend → Proxy → Clientupstream backend {
server 10.0.1.101:3000;
server 10.0.1.102:3000;
# Giữ 32 idle connections sống mỗi worker
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # Bật keepalive tới upstream
}
}Buffering
Control cách proxy buffer responses từ backends:
server {
location /api/ {
proxy_pass http://backend;
# Buffer backend response
proxy_buffering on;
proxy_buffer_size 4k; # Buffer cho phần đầu response
proxy_buffers 8 16k; # 8 buffers mỗi cái 16k
proxy_busy_buffers_size 32k; # Max size trước khi gửi cho client
}
# Tắt buffering cho streaming endpoints
location /api/stream/ {
proxy_pass http://backend;
proxy_buffering off;
}
}Timeouts
Set timeouts phù hợp để tránh hanging connections:
server {
# Thời gian thiết lập connection tới backend
proxy_connect_timeout 5s;
# Thời gian đọc response từ backend
proxy_read_timeout 60s;
# Thời gian gửi request tới backend
proxy_send_timeout 10s;
# Client request body timeout
client_body_timeout 10s;
# Client response timeout
send_timeout 10s;
# Keep-alive timeout
keepalive_timeout 65s;
}14. Common Patterns
Blue-Green Deployment
Switch traffic giữa hai environments giống nhau:
# Blue environment (đang live)
upstream blue {
server 10.0.1.101:3000;
server 10.0.1.102:3000;
}
# Green environment (version mới)
upstream green {
server 10.0.2.101:3000;
server 10.0.2.102:3000;
}
# Toggle bằng cách đổi upstream
server {
location / {
proxy_pass http://blue; # Đổi thành "green" để switch
}
}Canary Deployment
Gửi một phần trăm traffic tới version mới:
upstream stable {
server 10.0.1.101:3000 weight=9;
server 10.0.1.102:3000 weight=9;
}
upstream canary {
server 10.0.2.101:3000 weight=1;
}
# Split traffic dùng map
split_clients "${remote_addr}" $backend {
90% stable;
* canary;
}
server {
location / {
proxy_pass http://$backend;
}
}Health Check Endpoint
Backend nên expose health check endpoint cho proxy:
// Express.js health check
app.get("/health", (_req, res) => {
const health = {
status: "ok",
uptime: process.uptime(),
timestamp: new Date().toISOString(),
};
try {
// Kiểm tra database connection
// await db.query("SELECT 1");
res.json(health);
} catch (error) {
res.status(503).json({
...health,
status: "error",
message: "Database connection failed",
});
}
});15. Troubleshooting
Các Vấn Đề Thường Gặp
| Vấn Đề | Nguyên Nhân | Cách Fix |
|---|---|---|
| 502 Bad Gateway | Backend down hoặc không respond | Kiểm tra backend health, tăng timeouts |
| 504 Gateway Timeout | Backend quá chậm | Tăng proxy_read_timeout, optimize backend |
| WebSocket drops | Thiếu upgrade headers | Thêm Upgrade và Connection headers |
| Sai client IP | Thiếu forwarded headers | Thêm X-Real-IP và X-Forwarded-For |
| Mixed content | Sai X-Forwarded-Proto | Set proxy_set_header X-Forwarded-Proto $scheme |
| Upload lớn fail | client_max_body_size quá nhỏ | Tăng client_max_body_size |
| CORS errors | Headers bị proxy strip | Thêm CORS headers trong proxy config |
Debugging Checklist
- Check backend trực tiếp:
curl http://127.0.0.1:3000— có hoạt động không qua proxy? - Check proxy logs:
tail -f /var/log/nginx/error.log - Check response headers:
curl -I https://example.com— tìmX-Cache-Status,Server - Test SSL:
openssl s_client -connect example.com:443— certificate chain OK? - Check upstream health:
curl http://backend:3000/health— backend healthy?
Tổng Kết
| Chủ Đề | Những Gì Đã Cover |
|---|---|
| Concept | Reverse proxy nằm giữa clients và servers, xử lý routing, security, và performance |
| Forward vs Reverse | Forward bảo vệ clients, reverse bảo vệ servers |
| SSL Termination | Chuyển encryption sang proxy, backends chạy plain HTTP |
| Caching | Cache responses ở proxy để giảm tải backend |
| Security | Ẩn servers, rate limit, filter requests, thêm security headers |
| Load Balancing | Phân phối traffic qua nhiều backend servers |
| WebSocket/gRPC | Xử lý connection upgrades và HTTP/2 streaming |
| API Gateway | Route requests tới các microservices khác nhau dựa trên path |
| Solutions | Nginx (production), Traefik (containers), Caddy (simplicity) |
| Performance | Connection pooling, compression, buffering, timeouts |
Key takeaways:
✅ Mọi production application nên nằm sau reverse proxy
✅ SSL termination ở proxy đơn giản hóa certificate management
✅ Caching là performance win lớn nhất cho read-heavy apps
✅ Proxy là security layer đầu tiên — rate limiting, IP filtering, header security
✅ Path-based routing biến reverse proxy thành API gateway
✅ Bắt đầu với Nginx cho hầu hết use cases, Traefik cho Docker, Caddy cho simplicity
✅ Luôn set proper timeouts, forwarded headers, và health checks
Reverse proxy không chỉ là infrastructure plumbing — đó là nơi performance, security, và deployment flexibility hội tụ. Setup một lần, cấu hình cho tốt, và backend của bạn thoải mái focus vào điều quan trọng: application logic.
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.