Web 22/09/2026 5 phút

Nginx reverse proxy: một cửa trước nhiều backend — đo round-robin và X-Forwarded

Reverse proxy đứng trước các server, thay mặt chúng trả lời client: cân bằng tải, kết thúc TLS, gom nhiều service sau một tên miền. Bài này dựng nginx proxy tới 3 backend, đo round-robin chia đúng 10/10/10 trên 30 request, và giải thích vì sao thiếu header X-Forwarded-* làm backend thấy sai IP và giao thức của client.

Web 22/09/2026 6 phút

Nginx phục vụ tĩnh và tối ưu hiệu năng: sendfile, cache, và đo bằng ab

Nginx phục vụ file tĩnh nhanh đến mức nào? Bài cuối sê-ri đo thật: sendfile (zero-copy) cho thông lượng ~281 MB/s và 4301 request/giây trên file 68KB, Cache-Control để trình duyệt khỏi tải lại, gzip nén 156 KB xuống 1.2 KB. Kèm một cái bẫy đo lường: ab mặc định HTTP/1.0 nên không nhận gzip — phải đo tỉ lệ nén bằng curl.

Lập trình 22/09/2026 8 phút

Phiên bản API: đo thật qua nginx cache — đánh phiên bản bằng header mà quên Vary là 100/200 client nhận sai bản

Ba cách đổi hợp đồng API khi còn client cũ đang gọi: phiên bản trong URL, phiên bản trong header Accept, và không đánh phiên bản mà chỉ thêm trường. Mình đặt nginx proxy_cache trước server Go rồi cho hai client xen kẽ đòi v1 và v2: cách URL và cách header có Vary: Accept đều đúng 200/200, còn header mà quên Vary thì 100/200 client nhận sai phiên bản — cache trả bản v1 cho client v2 mà không có lỗi nào. Đo thêm: client dùng decoder chặt vỡ ngay khi server chỉ thêm một trường, và lớp chuyển đổi v2 sang v1 tốn 14–17 µs, nằm trong nhiễu đo — cái giá của phiên bản không nằm ở CPU.

Lập trình 22/09/2026 8 phút

Cache-Control trên HTTP API: đo thật qua nginx — max-age=5 cắt 99% request tới origin, và lúc hết hạn stale-while-revalidate cho 50 client đồng thời chỉ lọt 1

Origin Go mất 40 ms mỗi request, nginx proxy_cache đứng trước làm cache dùng chung, client bắn 300 request trong 12 giây cho từng chỉ thị Cache-Control. Không header, no-store và private: cả 300 tới origin, p50 44 ms. max-age=5: 3 tới origin, p50 0,8 ms, dữ liệu cũ tối đa 5,93 giây. Thứ max-age không chữa được là khoảnh khắc hết hạn: 50 client gọi đúng lúc đó thì 50 request lọt tới origin; thêm stale-while-revalidate=30 thì chỉ 1 lọt, 49 client còn lại nhận bản cũ trong 4 ms. Kèm chuyện private bị cache dùng chung bỏ qua, và s-maxage để tách hạn cho cache dùng chung với trình duyệt.