Hieu Solutions
Công nghệ

Nginx, HAProxy hay Envoy? Benchmark thực tế

1 tháng 1, 1970
23 lượt xem
Nginx, HAProxy hay Envoy? Benchmark thực tế

Nginx, HAProxy hay Envoy? Benchmark thực tế

Nguyễn Trung Hưng • 07:50

State of DevOps VietNam 2026

Đây là cái task lười nhất mà muốn làm nhưng vẫn phải làm vì sắp đến tết :))

Đùa chứ thấy mấy anh em chia sẻ benchmark hữu ích sẵn có task ngâm từ 2 tháng trước của sếp giao mới done cho tết ấm no nên cũng chia sẻ luôn vì chắc cái này cũng là sự cân nhắc của nhiều anh em.

Bài toán này đến từ một hạ tầng phục vụ nội bộ bên tôi (và có nhánh ra cho partner thân thiết – nghĩ vậy cho dễ hình dung) về cơ bản thì vẫn chạy nhưng có vấn đề là hệ thống không hề chậm theo kiểu rõ ràng. Mà nó khiến trải nghiệm khó chịu như là:

  • Anh em lâu lâu than: “Sao API lúc nhanh lúc chậm?”
  • Webhook partner gửi log: “Thỉnh thoảng thấy timeout”
  • Grafana thì không báo đỏ, nhưng p95/p99 cứ nhích lên từng tuần, đặc biệt khi có đợt spike.

Tôi coi lại kiến trúc và thấy thứ đập ngay vào mắt: reverse proxy/gateway. Đây là tầng mà nếu bạn chọn đúng, bạn gần như quên nó tồn tại. Chọn sai… bạn sẽ sống cùng nó mỗi ngày.

Vậy là tôi quyết định benchmark cụ thể. 3 cái tên rất quen thuộc là:

  • Nginx : ai cũng biết, dễ triển khai, làm được nhiều thứ.
  • HAProxy : nổi tiếng về tính ổn định, chịu tải cao rất tốt.
  • Envoy : cloud-native, gRPC/HTTP2 mạnh, telemetry ngon.

Mục tiêu

Mục tiêu rõ ràng là không phải tool nào nhanh hơn 5%, mà là câu hỏi thực tế: Nếu giờ mình đặt nó ở gateway production, tool nào cho p99 ổn định nhất?

Bài toán benchmark

Tôi chọn một bài toán mà tôi gặp hàng ngày:

  1. REST API keep-alive (chiếm phần lớn traffic): JSON nhỏ, request/response vài KB
  2. Webhook (đáng ghét nhất): nhiều client không reuse connection -> TLS handshake nhiều
  3. HTTP/2 (phần web/app mới): multiplexing
  4. gRPC unary (internal calls): cần p99 ổn và route theo header/metadata

Tôi chọn mức mà một đội nhỏ chạy SaaS vừa/nhỏ vẫn gặp: 5k–25k rps tùy kịch bản, đủ để thấy khác biệt.

Chuẩn bị hạ tầng

Tôi dùng 3 con VM để tránh benchmark bị nhiễu kết quả do cache cục bộ:

  • Loadgen : bắn traffic
  • Proxy : lần lượt chạy Nginx/HAProxy/Envoy
  • Backend : service Go đơn giản (HTTP + gRPC)

Cấu hình mỗi máy: 4 vCPU, 8GB RAM, Ubuntu 22.04. Latency nội bộ ~0.3-0.8ms.

Backend không phải hello world: tôi cho nó làm một chút CPU nhẹ (parse + marshal) để giống API thật. Và tôi bật TLS termination ở proxy.

Tôi chuẩn hóa điều kiện để fair (đo cái cần đo)

  • Tắt access log (log nhiều là giết benchmark)
  • Cùng TLS policy (TLS1.3, cipher suite tương tự)
  • Backend không đổi
  • Tăng ulimit -n, backlog… đủ để test không chết vì OS

Kịch bản tôi chạy

Tôi chạy 4 kịch bản riêng:

A) REST keep-alive (HTTP/1.1)

  • 500 concurrent
  • Target ~20k rps
  • Chạy 60s (warm-up 20s)

B) Webhook/short connection

  • 1k concurrent
  • Target ~5k rps
  • Cố tình giảm connection reuse để giả lập client khó chịu

C) HTTP/2

  • Ít connection nhưng nhiều stream
  • Target ~15k rps

D) gRPC unary

  • 500 concurrent
  • Target ~10k rps

Metric tôi quan tâm nhất: p95/p99error rate.

Kết quả

A) REST keep-alive tầng giao diện của hệ thống

Proxy RPS đạt được p95 p99 CPU proxy RAM proxy
HAProxy ~22.1k ~11.8ms ~18.6ms ~310% ~55MB
Nginx ~20.3k ~13.5ms ~22.4ms ~330% ~90MB
Envoy ~18.4k ~16.1ms ~27.9ms ~360% ~260MB

Cảm giác của tôi khá rõ: HAProxy cho thấy sự tối ưu vượt trội. Nginx thì không hề tệ. Nhưng Envoy rõ ràng nặng hơn trong bài toán REST keep-alive.

B) Webhook/short connection nơi chi phí TLS bắt đầu phát sinh đáng kể

Proxy RPS đạt được p95 p99 Error
HAProxy ~5.3k ~41ms ~55ms ~0.1%
Nginx ~5.0k ~45ms ~60ms ~0.2%
Envoy ~4.6k ~55ms ~75ms ~0.4%

Điểm rút ra: nếu hệ thống có nhiều webhook hoặc client không tái sử dụng kết nối, quá trình TLS handshake trở thành chi phí tài nguyên. Ở kịch bản này, HAProxy vẫn giữ lợi thế.

C) HTTP/2 — Envoy bắt đầu khẳng định ưu thế

Proxy RPS đạt được p95 p99
Envoy ~15.2k ~12.2ms ~20.1ms
HAProxy ~14.4k ~13.0ms ~23.4ms
Nginx ~13.8k ~14.6ms ~25.2ms

Envoy đúng là sinh ra cho các bài toán cloud-native, protocol hiện đại. Khi vào đúng bài, chỉ số vận hành rất ấn tượng.

D) gRPC unary — vì sao service mesh chọn Envoy

Proxy RPS đạt được p95 p99
Envoy ~10.6k ~10.5ms ~18.2ms
HAProxy ~10.1k ~11.4ms ~20.6ms
Nginx ~9.4k ~13.7ms ~24.9ms

Envoy hỗ trợ gRPC một cách tối ưu (native support). Khi triển khai các kiến trúc phức tạp như routing, canary, telemetry hay mTLS, Envoy giúp giảm thiểu việc phải tùy biến các thành phần phụ trợ.

Những cú ngã (để mọi người khỏi tự lừa mình)

  1. Quên tắt access log -> số liệu tụt, CPU tăng.
  2. Test backend quá basic -> kết quả không thực tế.
  3. Không tách keep-alive vs short connection -> kết luận bị nhiễu.
  4. Quên tăng ulimit -n -> lỗi connect xuất hiện khi concurrency cao.

Benchmark không khó. Khó là làm sao để benchmark không nói dối mình.

Sau tất cả đúc kết được gì?

Nếu tôi chỉ được chọn 1 con cho gateway public phục vụ không quá lớn, tôi sẽ chọn:

HAProxy cho edge gateway

Vì:

  • REST keep-alive: p99 ổn định, RPS cao, tài nguyên tối ưu.
  • Webhook short connection: chống chịu tốt hơn khi handshake liên tục.
  • Vận hành: cấu hình minh bạch, ít overhead.

Envoy cho internal gRPC/mesh-ish

  • HTTP/2/gRPC vào đúng bài thì rất đẹp.
  • Traffic management, telemetry, dynamic config: Envoy phù hợp hệ sinh thái.

Nginx là lựa chọn hợp lý nếu team đã quen

Nginx vẫn là lựa chọn cực kỳ tin cậy, đặc biệt khi đội ngũ đã có kinh nghiệm vận hành.

Lời kết

Gateway không phải nơi để thể hiện đẳng cấp công nghệ. Gateway là nơi để người dùng không phải nghĩ về nó.

Nếu mọi người muốn, tôi sẽ viết thêm một phần phụ lục gồm:

  • config tối thiểu fair cho Nginx/HAProxy/Envoy
  • lệnh chạy wrk2/h2load/ghz
  • template ghi kết quả để share nội bộ

Tags: Benchmark, Case Study, Envoy, HAProxy, Nginx

💬 Bạn thấy bài viết này thế nào?

Chia sẻ suy nghĩ của bạn hoặc kết nối với tôi trên mạng xã hội!