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

HTTP/2 multiplexing trong Go: nhiều request song song trên một kết nối, xóa head-of-line blocking

HTTP/2 chia mỗi request thành một stream độc lập chạy song song trên cùng một kết nối TCP, xóa head-of-line blocking của HTTP/1.1. Đo thật trong Go 1.23: 20 request trên một kết nối xong 54ms với HTTP/2 so với 1,136 giây với HTTP/1.1 — nhanh hơn 21 lần.

Web 22/09/2026 6 phút

HTTP/1.1 vs HTTP/2: multiplexing nhiều luồng trên một kết nối — đo thật

HTTP/1.1 gửi request tuần tự trên mỗi kết nối, nên response chậm chặn hết phần sau (head-of-line blocking) — trình duyệt phải mở tới 6 kết nối để lách. HTTP/2 chia message thành frame nhị phân, đan xen nhiều luồng trên một kết nối. Bài này đo thật bằng nginx và curl: thương lượng giao thức, log server xác nhận, và multiplexing nhanh hơn khi tải nhiều tài nguyên.

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

HTTP/2 multiplexing: 300 request song song trên đúng một kết nối

HTTP/1.1 chỉ chạy một request tại một thời điểm trên mỗi kết nối (head-of-line blocking), nên phải mở nhiều kết nối để làm việc song song. HTTP/2 đan xen nhiều stream trên một kết nối. Bài này chạy thật trong Go: 300 request song song qua HTTP/2 mở 0 kết nối mới (dùng lại 1 kết nối), còn HTTP/1.1 mở 221 — và HTTP/2 nhanh gấp gần 4 lần. Kèm lý do vì sao vẫn cần HTTP/3.

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

Load balancing phía client trong gRPC: vì sao LB kiểu HTTP/1 dồn hết vào một server, và round-robin chia đều thế nào

Đặt một load balancer thường trước gRPC là một bẫy: vì gRPC giữ một kết nối HTTP/2 lâu dài, LB mức kết nối (L4) ghim mọi request vào đúng một backend. Bài này đo thật trong go-lab: chạy 3 server, dùng client-side round-robin, gọi 300 RPC — chia gần như hoàn hảo 100/99/101 giữa ba server. Hiểu vì sao gRPC cần cân tải ở mức RPC (client-side hoặc proxy L7), không phải mức kết nối.