Chương 41. Reverse proxy và load balancer
Ở chương trước, ta nói:
Production không phải localhost lớn hơn một chút.
Một trong những khác biệt đầu tiên của production là:
Request từ user thường không đi thẳng vào app server.
Nó thường đi qua một hoặc nhiều lớp phía trước:
- CDN.
- WAF.
- Reverse proxy.
- Load balancer.
- API Gateway.
- Ingress controller.
Chương này tập trung vào hai khái niệm rất quan trọng:
Reverse proxy.
Load balancer.
Thông điệp chính của chương:
> Reverse proxy là cửa trước nhận request thay app. Load balancer là người chia request sang nhiều app server. Chúng giúp production ổn hơn, nhưng cũng thêm các vấn đề như health check, timeout, TLS termination, header, log và cấu hình sai.
---
41.1. Ví dụ dễ hiểu: lễ tân và nhiều quầy xử lý
Hãy tưởng tượng một văn phòng có nhiều quầy xử lý hồ sơ.
Khách không tự chạy vào từng phòng tìm nhân viên.
Khách đến quầy lễ tân.
Lễ tân:
- Nhận yêu cầu.
- Kiểm tra yêu cầu cơ bản.
- Chuyển khách đến đúng quầy.
- Không chuyển khách đến quầy đang đóng.
- Có thể nói khách chờ nếu quá tải.
Nếu có nhiều quầy giống nhau, lễ tân chia khách:
Khách 1 -> Quầy A
Khách 2 -> Quầy B
Khách 3 -> Quầy C
Trong web app:
Reverse proxy/load balancer giống quầy lễ tân.
App server giống các quầy xử lý.
User không cần biết request thật sự được xử lý bởi server nào.
---
41.2. Khi không có reverse proxy
Ở localhost, bạn thường chạy:
FastAPI/Django/Node app trực tiếp ở port 8000.
Rồi mở:
http://localhost:8000
Điều này ổn để dev.
Nhưng production thường cần nhiều hơn:
- HTTPS.
- Domain thật.
- Static file.
- Timeout.
- Log truy cập.
- Request size limit.
- Nhiều app instance.
- Health check.
- Graceful deploy.
- Chặn request quá lớn.
- Route nhiều service.
App framework không nhất thiết nên tự làm hết những việc này.
Vì vậy ta đặt một lớp phía trước.
---
41.3. Reverse proxy là gì?
Reverse proxy là server đứng trước backend app.
User gọi reverse proxy.
Reverse proxy gọi app server phía sau.
Luồng:
Browser
-> Reverse proxy
-> App server
Ví dụ:
Browser gọi https://app.example.com
Nginx nhận request
Nginx chuyển tới FastAPI ở http://127.0.0.1:8000
FastAPI xử lý
Nginx trả response về browser
User không biết app thật chạy ở đâu.
User chỉ thấy domain public.
---
41.4. Reverse proxy làm gì?
Reverse proxy có thể làm nhiều việc:
- Nhận request public.
- Chuyển request vào app nội bộ.
- Terminate TLS.
- Serve static files.
- Nén response.
- Giới hạn request body size.
- Set header.
- Ghi access log.
- Route theo path/domain.
- Chặn một số request xấu cơ bản.
- Timeout request chậm.
Ví dụ:
/api/* -> backend app
/static/* -> static files
/media/* -> object storage/CDN hoặc file server
Reverse proxy là lớp rất phổ biến trong production.
Các công cụ thường gặp:
- Nginx.
- Caddy.
- Apache httpd.
- HAProxy.
- Envoy.
- Traefik.
---
41.5. Reverse proxy khác forward proxy thế nào?
Forward proxy đứng về phía client.
Ví dụ:
User -> Forward proxy -> Internet
Reverse proxy đứng về phía server.
Ví dụ:
User -> Reverse proxy -> App servers
Nói dễ nhớ:
Forward proxy che client.
Reverse proxy che server.
Trong chương này, ta nói về reverse proxy.
---
41.6. Load balancer là gì?
Load balancer là thành phần chia traffic sang nhiều backend.
Luồng:
Browser
-> Load balancer
-> App server 1
-> App server 2
-> App server 3
Nếu có 3 app server, load balancer quyết định request nào đi đâu.
Ví dụ:
Request 1 -> App 1
Request 2 -> App 2
Request 3 -> App 3
Request 4 -> App 1
Mục tiêu:
- Chia tải.
- Tránh gửi request đến server lỗi.
- Hỗ trợ scale ngang.
- Hỗ trợ deploy dần.
- Tạo một endpoint ổn định cho user.
---
41.7. Reverse proxy và load balancer có phải một không?
Không hoàn toàn.
Nhưng trong thực tế, một công cụ có thể làm cả hai.
Reverse proxy nhấn mạnh:
Đứng trước app và chuyển tiếp request.
Load balancer nhấn mạnh:
Chia request sang nhiều backend.
Ví dụ Nginx có thể vừa là reverse proxy vừa load balance.
Cloud load balancer cũng có thể terminate TLS và route request.
Vì vậy đừng mắc kẹt vào tên.
Hãy hỏi:
Nó đang nhận request thay app?
Nó đang chia request sang nhiều app?
Nó đang terminate TLS?
Nó đang health check backend?
Chức năng quan trọng hơn nhãn.
---
41.8. Một server vẫn có thể dùng reverse proxy
Nhiều người nghĩ load balancer chỉ có ích khi có nhiều server.
Đúng với phần chia tải.
Nhưng reverse proxy vẫn rất hữu ích với một server.
Ví dụ:
Internet
-> Nginx/Caddy
-> App process ở port 8000
Reverse proxy giúp:
- Cấp HTTPS.
- Redirect HTTP sang HTTPS.
- Serve static file.
- Giới hạn upload size.
- Timeout.
- Log access.
- Che app port khỏi internet.
- Dễ sau này thêm app instance.
Một server production nhỏ vẫn nên có lớp cửa trước rõ ràng.
---
41.9. TLS termination là gì?
TLS termination nghĩa là:
Kết nối HTTPS được giải mã tại reverse proxy/load balancer.
Luồng:
Browser --HTTPS--> Load balancer --HTTP nội bộ--> App
Hoặc:
Browser --HTTPS--> Load balancer --HTTPS nội bộ--> App
Load balancer giữ certificate và xử lý TLS.
App phía sau có thể nhận HTTP nội bộ.
Ưu điểm:
- App không cần tự quản certificate.
- Cấu hình HTTPS tập trung.
- Dễ rotate certificate.
- Load balancer có thể dùng certificate managed.
Nhưng cần nhớ:
> Nếu TLS terminate ở proxy, app phải biết request gốc là HTTPS qua header đúng và cấu hình tin proxy đúng.
---
41.10. X-Forwarded-Proto và X-Forwarded-For
Khi proxy chuyển request vào app, app thấy request đến từ proxy.
Vì vậy proxy thường thêm header:
X-Forwarded-For: IP thật của client
X-Forwarded-Proto: https
X-Forwarded-Host: app.example.com
App dùng các header này để biết:
- Client IP thật.
- Request gốc là HTTP hay HTTPS.
- Host gốc là gì.
Nhưng cẩn thận:
> Chỉ tin forwarded headers từ proxy đáng tin.
Nếu app public trực tiếp và attacker tự gửi:
X-Forwarded-For: 1.2.3.4
app có thể bị lừa.
Vì vậy app/proxy cần cấu hình trusted proxy rõ ràng.
---
41.11. Client IP thật quan trọng ở đâu?
Client IP dùng cho:
- Rate limiting.
- Security log.
- Audit.
- Fraud detection.
- Geo routing.
- Debug.
Nếu app chỉ thấy IP của load balancer, mọi user sẽ giống cùng một IP.
Rate limit sẽ sai.
Log audit sẽ kém giá trị.
Vì vậy cần cấu hình:
Proxy truyền client IP.
App tin proxy đúng cách.
Trong cloud, đôi khi dùng header khác hoặc proxy protocol.
Điểm chính:
> Khi có proxy, app không tự nhiên biết IP thật nếu không cấu hình.
---
41.12. Health check là gì?
Health check là cách load balancer kiểm tra backend còn khỏe không.
Ví dụ:
GET /health
Nếu app trả OK, load balancer gửi traffic.
Nếu app lỗi, load balancer ngừng gửi traffic.
Luồng:
Load balancer -> App 1 /health -> OK
Load balancer -> App 2 /health -> FAIL
Traffic chỉ gửi App 1.
Health check giúp tránh user bị gửi đến server chết.
---
41.13. Liveness và readiness
Chương trước đã nhắc qua.
Liveness:
Process còn sống không?
Readiness:
Service sẵn sàng nhận traffic chưa?
Ví dụ app vừa khởi động:
Process sống.
Nhưng chưa kết nối database xong.
Liveness có thể OK.
Readiness chưa OK.
Load balancer nên dựa vào readiness để gửi traffic.
Nếu không, user có thể bị gửi đến app chưa sẵn sàng.
---
41.14. Health check không nên quá nặng
Health check được gọi thường xuyên.
Không nên để /health làm việc quá nặng:
- Query database phức tạp.
- Gọi external API.
- Kiểm tra hàng chục service.
- Tạo log quá nhiều.
Nếu health check nặng, chính health check có thể gây tải.
Một cách thực dụng:
/live:
process còn sống
/ready:
app sẵn sàng nhận request cơ bản
dependency quan trọng ở mức cần thiết
Không cần health check chứng minh toàn bộ hệ thống hoàn hảo.
Nó chỉ cần giúp load balancer quyết định gửi traffic hay không.
---
41.15. Timeout ở proxy
Proxy/load balancer thường có timeout.
Ví dụ:
Client timeout.
Proxy read timeout.
Proxy connect timeout.
Upstream timeout.
Idle timeout.
Nếu app xử lý lâu hơn timeout, proxy sẽ cắt request.
Ví dụ:
Proxy timeout 60 giây.
Backend gọi AI 90 giây.
User nhận lỗi timeout dù backend có thể vẫn đang chạy.
Đây là lý do việc dài không nên xử lý trong request web.
Nên:
Tạo job.
Trả response nhanh.
Worker xử lý nền.
Client xem trạng thái.
Timeout ở proxy không phải chi tiết cấu hình nhỏ.
Nó ảnh hưởng kiến trúc.
---
41.16. Request body size limit
Proxy thường giới hạn kích thước request body.
Ví dụ Nginx có:
client_max_body_size
Nếu user upload file lớn hơn limit, proxy từ chối trước khi tới app.
Điều này tốt nếu cấu hình đúng.
Nhưng nếu app cho upload 50 MB còn proxy chỉ cho 10 MB, user sẽ lỗi.
Với file lớn, thường tốt hơn:
Browser upload trực tiếp lên object storage bằng presigned URL.
Proxy không phải đường tốt để đẩy video/file lớn qua app.
---
41.17. Static files
Reverse proxy có thể serve static files tốt hơn app.
Ví dụ:
/static/app.js
/static/style.css
/static/logo.png
Nginx/Caddy/CDN phục vụ static asset rất tốt.
App framework nên tập trung xử lý logic động.
Production thường dùng:
Browser -> CDN/reverse proxy -> static files
Browser -> reverse proxy -> app API
Với asset public nhiều người tải, CDN còn tốt hơn reverse proxy đơn lẻ.
---
41.18. Compression
Proxy có thể nén response.
Ví dụ:
- gzip.
- brotli.
Nén giúp giảm bandwidth và tăng tốc tải text asset/API response.
Nhưng không phải mọi thứ cần nén.
Ảnh/video thường đã nén sẵn.
File lớn cần cân nhắc CPU.
Thông điệp:
> Proxy có thể xử lý một số việc HTTP-level tốt hơn app.
---
41.19. Load balancing algorithm
Load balancer cần chọn backend.
Các cách phổ biến:
Round robin:
Chia lần lượt App 1, App 2, App 3.
Least connections:
Gửi đến backend đang ít connection hơn.
Weighted:
Server mạnh hơn nhận nhiều traffic hơn.
IP hash/sticky:
Cùng client thường vào cùng backend.
Không cần nhớ sâu ngay.
Nhưng cần biết:
> Load balancer không tự hiểu nghiệp vụ. Nó chỉ chia traffic theo thuật toán/cấu hình.
---
41.20. Sticky session
Sticky session nghĩa là:
Cùng user/client được gửi về cùng app server.
Điều này hữu ích nếu app lưu session/state trong memory.
Nhưng đó cũng là dấu hiệu thiết kế cần cẩn thận.
Nếu server A chết, state trong memory mất.
Tốt hơn với web app scale ngang:
Session nằm trong Redis/database.
File nằm object storage.
Job nằm queue.
App server stateless nhất có thể.
Khi app stateless, request có thể đi vào bất kỳ server nào.
Load balancing dễ hơn nhiều.
---
41.21. Stateless app server
Stateless app server nghĩa là app process không giữ state quan trọng trong memory local.
Ví dụ không nên giữ trong memory:
- Session quan trọng.
- Job pending.
- Upload state quan trọng.
- File user upload.
- Cache bắt buộc đúng.
State nên nằm ở:
- Database.
- Redis.
- Queue.
- Object storage.
Stateless không có nghĩa app không có state.
Nó nghĩa là:
State quan trọng không phụ thuộc vào một app process cụ thể.
Điều này giúp scale ngang.
---
41.22. Scale ngang là gì?
Scale ngang là thêm nhiều instance/server giống nhau.
Ví dụ:
App server 1
App server 2
App server 3
Load balancer chia traffic vào chúng.
Ưu điểm:
- Tăng capacity.
- Một instance chết vẫn còn instance khác.
- Deploy rolling dễ hơn.
Điều kiện:
- App tương đối stateless.
- Session/shared state xử lý đúng.
- Database/queue chịu được tải.
- Health check tốt.
- Observability rõ.
Scale ngang app server dễ hơn scale database, nhưng vẫn cần thiết kế đúng.
---
41.23. Khi nào một server là đủ?
Một server có thể đủ khi:
- Traffic thấp.
- Team nhỏ.
- App mới ra mắt.
- Downtime ngắn chấp nhận được.
- Tải chủ yếu không lớn.
- Database/file/backup được xử lý cẩn thận.
- Có monitoring cơ bản.
Một server không xấu.
Rất nhiều sản phẩm bắt đầu tốt với:
Một VM.
Nginx/Caddy.
App process.
PostgreSQL managed hoặc local được backup tốt.
Redis nếu cần.
Object storage.
Điều quan trọng là:
Biết giới hạn và có đường nâng cấp.
Đừng scale ngang chỉ để trông chuyên nghiệp.
---
41.24. Khi nào cần nhiều app server?
Cần nghĩ đến nhiều app server khi:
- Một server không đủ CPU/RAM.
- Traffic tăng rõ.
- Cần deploy không downtime.
- Cần chịu lỗi app instance.
- Request bị queue ở app server.
- Latency tăng khi concurrent user tăng.
- Cần tách vùng/availability zone.
Nhưng trước khi thêm app server, hãy kiểm tra:
- Database có phải bottleneck không?
- Worker có phải bottleneck không?
- External API có phải bottleneck không?
- Query có chậm không?
- Cache có giúp không?
- App có stateless chưa?
Nếu bottleneck là database hoặc AI provider, thêm app server chưa chắc giúp.
---
41.25. Load balancer không giải quyết mọi bottleneck
Load balancer giúp chia request vào nhiều app server.
Nhưng nếu mọi request đều đánh vào cùng database đang quá tải:
Thêm app server có thể làm database chết nhanh hơn.
Nếu mọi request đều gọi AI API bị quota:
Thêm app server không làm AI API nhanh hơn.
Nếu worker concurrency là 4:
Thêm web server không làm job chấm nhanh hơn.
Vì vậy khi hệ thống chậm, phải tìm bottleneck thật.
Load balancer là công cụ chia tải ở tầng app.
Không phải thuốc chữa mọi chậm.
---
41.26. Rolling deploy
Rolling deploy là deploy từng instance một.
Ví dụ có 3 app server:
App 1 -> deploy version mới -> healthy
App 2 -> deploy version mới -> healthy
App 3 -> deploy version mới -> healthy
Trong lúc đó, load balancer chỉ gửi traffic đến instance healthy.
Lợi ích:
- Giảm downtime.
- Có thể phát hiện lỗi sớm.
- Không tắt toàn bộ hệ thống cùng lúc.
Điều kiện:
- Health check đúng.
- App version cũ/mới tương thích trong một thời gian.
- Migration an toàn.
- Graceful shutdown.
Rolling deploy không cứu được migration phá schema.
Nó chỉ là một phần của deploy an toàn.
---
41.27. Blue-green deploy
Blue-green deploy có hai môi trường:
Blue: version hiện tại
Green: version mới
Deploy version mới vào Green.
Test Green.
Sau đó chuyển traffic từ Blue sang Green.
Nếu lỗi, chuyển lại Blue.
Ưu điểm:
- Rollback nhanh ở tầng traffic.
- Môi trường mới được chuẩn bị trước.
Nhược điểm:
- Tốn tài nguyên hơn.
- Database migration vẫn cần tương thích.
- State/session/job cần cẩn thận.
Load balancer/proxy thường là nơi chuyển traffic.
---
41.28. Canary deploy
Canary deploy là cho một phần nhỏ traffic dùng version mới.
Ví dụ:
1% traffic -> version mới
99% traffic -> version cũ
Nếu ổn:
10%
50%
100%
Canary giúp giảm rủi ro.
Nhưng cần:
- Metrics tốt.
- Error tracking.
- Khả năng route traffic.
- Feature flag nếu cần.
- Dữ liệu/schema tương thích.
Canary không có monitoring thì giống thả thử mà không nhìn.
---
41.29. Connection draining
Khi muốn gỡ một app server khỏi load balancer, không nên cắt ngay request đang chạy.
Connection draining nghĩa là:
Ngừng gửi request mới đến server đó.
Đợi request đang chạy hoàn tất.
Sau đó mới tắt server.
Điều này giúp deploy/restart êm hơn.
Nếu request dài hoặc streaming, cần timeout hợp lý.
Với job lâu, tốt nhất đừng xử lý trong request web.
---
41.30. WebSocket và load balancer
WebSocket giữ kết nối lâu.
Load balancer cần hỗ trợ:
- Upgrade connection.
- Idle timeout phù hợp.
- Sticky session nếu backend giữ state connection local.
- Scale connection.
Nếu app dùng WebSocket cho realtime, load balancer timeout mặc định có thể cắt kết nối.
Cần cấu hình riêng.
Và nếu nhiều app server, cần nghĩ:
Message gửi tới user đang connected ở server nào?
Thường cần Pub/Sub hoặc realtime service phía sau.
---
41.31. Long polling/SSE và proxy timeout
SSE và long polling cũng giữ request lâu hơn request API bình thường.
Proxy timeout quá ngắn sẽ cắt.
Cần cấu hình:
- Read timeout.
- Buffering.
- Keep-alive.
- Retry behavior.
Nếu chỉ dùng request ngắn, cấu hình đơn giản.
Nếu dùng realtime, proxy/load balancer trở thành phần quan trọng của thiết kế.
---
41.32. Buffering
Một số reverse proxy buffer request/response.
Buffering có thể tốt:
- Giảm áp lực app với client chậm.
- Tối ưu truyền dữ liệu.
Nhưng có thể gây vấn đề với streaming:
App gửi từng chunk.
Proxy giữ lại tới khi đủ buffer.
Client không thấy realtime.
Với SSE/streaming response, có thể cần tắt buffering cho route đó.
Đây là ví dụ production khác localhost:
Local streaming chạy.
Qua proxy thì không stream vì bị buffer.
---
41.33. Path-based routing
Reverse proxy/load balancer có thể route theo path.
Ví dụ:
/api/* -> API service
/admin/* -> Admin app
/static/* -> Static files
/uploads/* -> File service/CDN
Điều này tiện khi có nhiều backend sau cùng một domain.
Nhưng đừng để routing trở thành mớ rối.
Nếu nhiều service, nhiều auth rule, nhiều transform phức tạp, có thể bắt đầu cần API Gateway.
Chương sau sẽ nói kỹ hơn.
---
41.34. Host-based routing
Route theo domain/subdomain:
app.example.com -> user app
admin.example.com -> admin app
api.example.com -> API
Host-based routing giúp tách rõ bề mặt.
Ví dụ:
Admin app có auth/rate limit/log riêng.
API public có policy riêng.
Cấu hình domain, TLS certificate, CORS, cookie domain đều liên quan.
Một thay đổi nhỏ ở host/subdomain có thể ảnh hưởng auth.
---
41.35. Access log ở proxy
Proxy thường ghi access log:
client_ip
method
path
status
response_time
upstream_time
request_size
response_size
user_agent
Log này rất hữu ích để biết:
- Endpoint nào chậm.
- Client nào gọi nhiều.
- Status 5xx tăng ở đâu.
- Request body quá lớn.
- Upstream timeout.
- Bot scan path nào.
App log và proxy log bổ sung cho nhau.
Proxy thấy traffic vào cửa.
App thấy logic bên trong.
---
41.36. 502, 503, 504 nghĩa là gì?
Các lỗi proxy hay gặp:
502 Bad Gateway:
Proxy không nhận được response hợp lệ từ upstream.
App crash, connection refused, protocol lỗi.
503 Service Unavailable:
Không có backend healthy hoặc service unavailable.
504 Gateway Timeout:
Upstream xử lý quá lâu, proxy timeout.
Khi user báo lỗi 502/503/504, đừng chỉ nhìn code app.
Hãy nhìn:
- Proxy log.
- App health.
- App crash log.
- Timeout config.
- Backend pool.
- Deploy vừa xảy ra không.
---
41.37. AI Judge: request path production
Một request AI Judge production có thể đi:
Browser
-> CDN/WAF nếu có
-> Load balancer
-> Reverse proxy/Ingress
-> API app server
-> Database/Queue/Object storage
-> Worker
-> AI provider
Không phải mọi request đều đi hết đường này.
Ví dụ:
Static asset:
Browser -> CDN
API submit:
Browser -> LB/proxy -> API -> DB/Queue
File upload lớn:
Browser -> API xin presigned URL
Browser -> Object storage upload trực tiếp
Grading:
Worker -> AI provider
Hiểu request path giúp debug đúng nơi.
Nếu upload lỗi, chưa chắc lỗi ở API.
Có thể proxy body limit, object storage policy, CORS storage, hoặc presigned URL hết hạn.
---
41.38. AI Judge: timeout ở proxy
Nếu AI Judge gọi AI trong request:
POST /grade
-> backend gọi AI 90 giây
-> proxy timeout 60 giây
-> user nhận 504
Dù backend sau đó có thể vẫn nhận kết quả.
Thiết kế tốt hơn:
POST /submissions
-> tạo job
-> trả 202 Accepted hoặc status queued
-> worker chấm
-> frontend polling/SSE/WebSocket xem trạng thái
Proxy timeout thúc ép ta thiết kế request ngắn, job nền rõ.
---
41.39. AI Judge: scale web và scale worker khác nhau
Load balancer scale web app:
Nhiều API server nhận request nộp bài, xem kết quả, dashboard.
Nhưng chấm bài nằm ở worker:
Queue -> worker pool -> AI provider
Nếu web traffic cao, thêm API server có thể giúp.
Nếu job chấm backlog cao, cần:
- Tăng worker concurrency nếu quota cho phép.
- Tối ưu retry.
- Tính quota AI.
- Tách queue ưu tiên.
- Giám sát worker.
Đừng nhầm scale web server với scale job processing.
---
41.40. Khi nào reverse proxy/load balancer trở thành điểm nghẽn?
Proxy/LB cũng có giới hạn.
Nó có thể nghẽn vì:
- CPU TLS quá cao.
- Connection quá nhiều.
- Config timeout sai.
- Buffer lớn.
- Log quá nặng.
- Một instance proxy duy nhất.
- Rule routing quá phức tạp.
- Rate limit state không scale.
Managed load balancer/CDN thường xử lý nhiều việc này tốt.
Nếu tự host Nginx/HAProxy, cần monitor:
- Connection.
- CPU/RAM.
- 4xx/5xx.
- Upstream latency.
- Active upstream.
- TLS errors.
Không có thành phần nào miễn nhiễm với bottleneck.
---
41.41. Managed load balancer hay tự host?
Managed load balancer:
- AWS ALB/NLB.
- Google Cloud Load Balancer.
- Azure Load Balancer/Application Gateway.
- Cloudflare.
- Fly/Render/Railway/Heroku platform routers.
Ưu điểm:
- Đỡ vận hành.
- Tích hợp health check.
- TLS managed.
- Scale tốt.
- Tích hợp cloud.
Nhược điểm:
- Chi phí.
- Vendor-specific.
- Ít kiểm soát sâu hơn tự host.
Tự host Nginx/HAProxy:
- Linh hoạt.
- Rẻ hơn ở quy mô nhỏ.
- Kiểm soát config.
Nhưng bạn phải tự vận hành.
Thực dụng:
> Nếu dùng cloud/platform tốt, dùng managed load balancer thường đáng tiền.
---
41.42. Một cấu hình nhỏ hợp lý
Với app nhỏ:
Cloudflare/Caddy/Nginx
-> App server
-> Managed PostgreSQL
-> Object storage
-> Queue/worker nếu cần
Một server app vẫn được.
Nhưng nên có:
- HTTPS.
- Reverse proxy.
- Process manager/container.
- Health check cơ bản.
- Backup database.
- Object storage cho file.
- Monitoring/log.
Đây là production nhỏ nhưng tử tế.
Không cần Kubernetes ngay.
---
41.43. Một cấu hình lớn hơn
Khi traffic tăng:
CDN/WAF
-> Managed Load Balancer
-> Multiple App Servers
-> Database/Redis/Queue/Object Storage
-> Worker Pools
Load balancer:
- Health check app.
- Chia traffic.
- Terminate TLS.
- Hỗ trợ rolling deploy.
App server:
- Stateless.
- Không lưu file local.
- Session dùng shared store nếu cần.
Worker:
- Scale riêng theo queue.
- Không đi qua load balancer cho job nội bộ trừ khi cần gọi service.
Đây là cấu trúc rất phổ biến.
---
41.44. Checklist trước khi đưa proxy/LB vào production
Hỏi:
- HTTPS đã cấu hình đúng chưa?
- HTTP có redirect sang HTTPS không?
- App có biết original scheme/host/client IP không?
- Trusted proxy header đã cấu hình chưa?
- Health check có nhẹ và đúng không?
- Timeout có phù hợp với request không?
- Request body size limit có khớp upload không?
- Static file route có đúng không?
- WebSocket/SSE có cần timeout/buffering riêng không?
- Access log có đủ thông tin không?
- Proxy có log secret/header nhạy cảm không?
- Khi app instance chết, LB có ngừng gửi traffic không?
- Khi deploy, có connection draining không?
- Nếu chỉ có một proxy, nó có thành single point of failure không?
Proxy là cửa trước.
Cửa trước cấu hình sai thì app tốt cũng khổ.
---
41.45. Bảng chọn nhanh
| Tình huống | Cách nghĩ thường hợp | |---|---| | Một app server production nhỏ | Reverse proxy + HTTPS vẫn rất hữu ích | | Nhiều app server | Load balancer + health check | | Request dài hơn proxy timeout | Chuyển sang job nền hoặc tăng timeout có lý do | | Upload file lớn | Presigned URL/object storage, tránh đi qua app nếu có thể | | Cần deploy ít downtime | Health check + rolling/blue-green/canary | | App cần scale ngang | Stateless app server + shared state | | WebSocket/SSE | Cấu hình timeout/buffering/upgrade riêng | | User IP bị mất | Forwarded headers/proxy protocol + trusted proxy | | 502/503/504 | Kiểm tra proxy log, upstream health, timeout, deploy | | Traffic còn thấp | Một server có thể đủ, nhưng vẫn cần backup/monitoring |
---
41.46. Tóm tắt bằng AI Judge
Với AI Judge:
Browser
-> Load balancer/reverse proxy
-> API servers
-> DB/Queue/Object storage
-> Workers
-> AI provider
Reverse proxy/load balancer giúp:
- HTTPS.
- Route request.
- Chia traffic vào nhiều API server.
- Ngừng gửi traffic đến server lỗi.
- Timeout request treo.
- Ghi access log.
- Hỗ trợ deploy an toàn hơn.
Nhưng nó không giải quyết:
- Worker quá ít.
- Gemini/API quota.
- Database query chậm.
- File upload thiết kế sai.
- Permission bug.
- Migration lỗi.
Ví dụ quan trọng:
Nếu chấm bài mất 90 giây,
đừng để request web chờ qua proxy.
Hãy dùng queue/worker và trả trạng thái processing.
Scale web server và scale worker là hai chuyện khác nhau.
---
41.47. Kết luận của chương
Reverse proxy và load balancer là lớp cửa trước của production web app.
Reverse proxy nhận request thay app, xử lý các việc HTTP-level như TLS, static files, timeout, header, log và routing.
Load balancer chia traffic sang nhiều backend healthy, giúp scale ngang và deploy an toàn hơn.
Nhưng chúng không phải phép màu.
Nếu bottleneck nằm ở database, worker, external API, queue, hoặc thiết kế request dài, load balancer không tự chữa được.
Thông điệp cần nhớ:
> Một server có thể đủ ở giai đoạn đầu. Nhưng dù một server hay nhiều server, production vẫn cần cửa trước rõ ràng, HTTPS đúng, timeout đúng, health check đúng, và state không phụ thuộc bừa vào một process.
Ở chương tiếp theo, ta sẽ nói về API Gateway: nó khác reverse proxy ở đâu, khi nào gateway giúp hệ thống gọn hơn, và khi nào gateway trở thành một điểm nghẽn phức tạp.