NGINX High Performance: Cấu hình Load Balancing & Layer 7 Persistence trên Ubuntu 20.04+
Summary: Hướng dẫn chi tiết cách triển khai Load Balancing và Layer 7 Persistence (Session Affinity) cho NGINX trên Ubuntu 20.04+ nhằm đảm bảo tính sẵn sàng cao (High Availability) và tối ưu hóa phân phối lưu lượng trong môi trường production.

Giới thiệu
Bài viết này trình bày cách cấu hình NGINX High Performance để thực hiện load balancing và quản lý persistence ở lớp ứng dụng (Layer 7) trên nền tảng Ubuntu 20.04+ hoặc các phân phối tương thích. Tài liệu tập trung vào cách sử dụng ngx_http_upstream_module để định nghĩa nhóm máy chủ backend và cách NGINX phân phối lưu lượng giữa chúng, đồng thời nêu rõ các tham số và chiến lược liên quan đến độ sẵn sàng và hiệu suất hệ thống. Các tham chiếu kỹ thuật từ tài liệu chính thức của NGINX cho phép triển khai một mô hình cân bằng tải ổn định, có khả năng mở rộng và dễ bảo trì trong môi trường sản xuất.
Kiến trúc và khái niệm cốt lõi
Nguyên lý cốt lõi của NGINX khi làm load balancer ở lớp ứng dụng được đóng gói trong module upstream. Module ngx_http_upstream_module cho phép định nghĩa một nhóm các máy chủ backend mà có thể được tham chiếu từ các directive như proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, và grpc_pass. Định nghĩa này nằm trong một khối upstream và có thể có nhiều máy chủ với các tham số khác nhau. Ví dụ một khối upstream có thể trỏ tới nhiều máy chủ và cả socket UNIX để tối ưu hóa hiệu suất và tính sẵn sàng.
Khái niệm cơ bản: một upstream định nghĩa một tập máy chủ mà NGINX có thể gửi request tới. Các máy chủ có thể ở các cổng khác nhau hoặc thậm chí là UNIX-domain socket. Mặc định, NGINX phân phối các yêu cầu giữa các máy chủ bằng phương pháp cân bằng vòng quay có trọng số (weighted round-robin). Điều này cho phép ưu tiên một máy chủ nhất định bằng cách gán trọng số cao cho nó để nhận nhiều yêu cầu hơn so với các máy chủ còn lại. Ngoài ra, NGINX hỗ trợ các phương pháp cân bằng khác như hash, ip_hash và random, để đáp ứng các yêu cầu khác nhau về persistence và phân bổ lưu lượng.
Các tham số quan trọng được định nghĩa cho mỗi máy chủ trong upstream:
- weight: xác định trọng số của máy chủ để ảnh hưởng tới phân phối lưu lượng. Trọng số càng cao, máy chủ nhận càng nhiều yêu cầu so với các máy chủ khác.
- max_conns: giới hạn số kết nối đồng thời tới máy chủ backend (một giới hạn áp dụng nếu upstream nằm trong RAM chia sẻ và có nhiều worker).
- max_fails: số lần thử không thành công liên tiếp với máy chủ, được đếm trong thời gian được chỉ định bởi fail_timeout để xem máy chủ có còn hợp lệ hay không.
- fail_timeout: khoảng thời gian trong đó một số lần thử không thành công được xem là máy chủ bị unavailable.
- backup: đánh dấu máy chủ là máy chủ sao lưu; các yêu cầu sẽ được chuyển tới máy chủ sao lưu khi các máy chủ chính không thể phục vụ.
- down: đánh dấu máy chủ là unavailable vĩnh viễn.
- resolve: quan sát sự thay đổi của địa chỉ IP tương ứng với tên miền của máy chủ và tự động cập nhật upstream mà không cần khởi động lại nginx (yêu cầu cấu hình resolver ở khối http hoặc upstream).
- service: cho phép tra cứu DNS SRV và thiết lập tên dịch vụ.
Để vận hành ở mức độ cao hơn, cơ chế kiểm tra sức khỏe (health checks) có thể được bật, nhưng trong các phiên bản thương mại của NGINX. Ví dụ trong tài liệu tham khảo, khối upstream có thể sử dụng health_check để theo dõi tình trạng của backend.
Điểm đặc thù quan trọng khác là cách xác định địa chỉ của backend. Địa chỉ có thể là tên miền hoặc địa chỉ IP, và nếu không chỉ định port thì mặc định sẽ là cổng 80. Một tên miền có thể resolve thành nhiều địa chỉ IP sẽ tạo ra nhiều máy chủ backend cùng lúc. Thêm vào đó, tham số resolve cho phép cập nhật địa chỉ khi thay đổi DNS mà không cần khởi động lại nginx. Ngược lại, tham số backup sẽ đánh dấu một máy chủ phụ để nhận yêu cầu khi các máy chủ chính gặp sự cố. Những khía cạnh này cho phép thiết kế cơ chế cân bằng tải bền vững và có khả năng phục hồi đúng theo nhu cầu vận hành.
Yêu cầu và chuẩn bị
Đối với kiến trúc NGINX High Performance triển khai trên nền tảng Ubuntu 20.04+ hoặc các bản phân phối tương thích, cần đảm bảo một số yếu tố cơ bản sau:
- Nguyên tắc cơ bản: NGINX được triển khai với các module cần thiết để định nghĩa upstream và thực thi proxy cho các backend HTTP hoặc các dạng kết nối khác (ví dụ FastCGI, uwsgi, memcached, grpc). Tham chiếu từ tài liệu cho upstream cho thấy các module như ngx_http_upstream_module và các module liên quan khác có thể được tích hợp tùy thuộc vào gói cài đặt của bạn.
- Khả năng đọc / cập nhật DNS cho upstream động: nếu bạn dùng resolve và SRV records, cần có resolver được chỉ định ở khối http hoặc upstream để cho phép cập nhật địa chỉ backend khi DNS thay đổi.
- Khả năng kiểm tra sức khỏe (health checks): một số tính năng nâng cao cho upstream có thể yêu cầu gói thương mại của NGINX để sử dụng health_check và các cơ chế phức tạp khác.
Trong tài liệu tham khảo, các khía cạnh trên nhấn mạnh sự linh hoạt của upstream và khả năng tinh chỉnh phân phối tải thông qua các tham số và các phương thức cân bằng để phù hợp với từng môi trường sản xuất.
Cấu hình chính
Phần cấu hình dưới đây minh họa một khối upstream cơ bản và một cấu hình server để phân phối lưu lượng đến nhiều backend. Đây là mẫu tham khảo và có thể được áp dụng trên Ubuntu 20.04+ hoặc các hệ thống tương đương có NGINX được biên dịch với module upstream.
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
listen 80;
location / {
proxy_pass http:// backend ;
}
}
Cấu hình ở trên cho phép phân phối tải qua các máy chủ backend xác định với các tham số trọng số, cổng khác nhau và cả socket UNIX. Máy chủ backup được gán để nhận yêu cầu khi các máy chủ chính gặp sự cố. Mặc định, NGINX sẽ sử dụng phương pháp cân bằng vòng quay có trọng số giữa các máy chủ trong upstream.
Để làm rõ cách phân phối lưu lượng, hãy tham khảo ví dụ dưới đây. Trong ví dụ này, mỗi chu kỳ 7 yêu cầu sẽ được phân phối như sau: 5 yêu cầu tới backend1.example.com, và mỗi máy chủ backend2 và backend3 nhận 1 yêu cầu. Điều này thể hiện rõ cơ chế trọng số tác động như thế nào tới phân bổ lưu lượng.
upstream dynamic {
zone upstream_dynamic 64k;
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
server 192.0.2.1 max_fails=3;
server backend3.example.com resolve;
server backend4.example.com service=http resolve;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http:// dynamic ;
health_check;
}
}
Ghi chú về mẫu nâng cao ở trên: khối upstream dynamic cho thấy cách định danh zone cho nhóm máy chủ, cho phép các máy chủ có các trạng thái khác nhau và khả năng tra cứu DNS SRV thông qua tham số service và resolve. Cú pháp health_check ở cuối khối server cho thấy một ví dụ về việc giám sát sức khỏe — điều này có thể được kích hoạt trong các phiên bản thương mại của NGINX để thực thi kiểm tra liên tục đối với các backend.
Cân bằng tải và persistence ở lớp 7
Ngữ cảnh cân bằng tải ở lớp 7 phụ thuộc vào cách bạn xác định các máy chủ backend và cách NGINX phân phối lưu lượng giữa chúng. Mặc định, upstream sử dụng phương pháp cân bằng vòng quay có trọng số, nhưng các phương pháp khác như hash, ip_hash và random cũng được nhắc tới như các tùy chọn cân bằng có thể áp dụng cho các tình huống khác nhau. Việc ưu tiên các backend hoặc thiết lập persistence có thể dựa vào các tham số của upstream và cách bạn cấu hình proxy_pass tới upstream để đảm bảo tính nhất quán của các phiên làm việc.
Ví dụ thực tế và giải thích cấu hình
- Upstream backend với năm máy chủ backend và hai máy chủ backup. Trọng số cao hơn cho backend1 để ưu tiên xử lý; các máy chủ backup nhận khi các máy chủ chính không khả dụng.
- Upstream dynamic cho phép quản lý địa chỉ động theo DNS và có tùy chọn resolve để cập nhật mà không cần restart nginx. Đoạn cấu hình mẫu cho health_check cho thấy tính năng giám sát sức khỏe có thể được kích hoạt khi cần thiết (điểm lưu ý là health_check có thể là phần của các phiên bản thương mại).
Bảo mật và tuân thủ
Khi triển khai load balancing ở lớp 7, cần lưu ý yếu tố bảo mật liên quan đến giao thức và TLS ở phía máy chủ. NGINX hỗ trợ các module liên quan như ngx_http_ssl_module để xử lý TLS cho các kết nối tới backend hoặc đi qua proxy. Việc xác thực và quản lý số lượng kết nối tới backend cũng có thể ảnh hưởng đến bảo mật và tuân thủ vận hành. Tài liệu tham khảo cho upstream cho thấy các module liên quan và các cơ chế để đảm bảo kết nối an toàn và hiệu quả, đồng thời cho phép giám sát và vận hành ở mức độ chấp nhận được trong môi trường prod.
Hiệu suất và tối ưu hóa
Hiệu suất của hệ thống phụ thuộc vào cách bạn cấu hình upstream và các tham số liên quan. Ví dụ, tham số weight cho mỗi máy chủ cho phép tối ưu hóa phân bổ tải theo mức độ ưu tiên của backend. Tham số max_conns giúp giới hạn số kết nối đồng thời đến từng backend, từ đó ngăn ngừa tình trạng quá tải và giảm thiểu tác động đến các backend khác. Failover và fail_timeout cho phép hệ thống quay vòng và phục hồi khi một backend gặp sự cố, giúp hệ thống duy trì khả năng phục vụ ổn định ngay cả khi một phần hệ thống gặp sự cố.
Quan sát và giám sát
Khả năng giám sát hiệu suất và tình trạng của upstream là một phần quan trọng của vận hành NGINX. Tài liệu liên quan cho thấy danh sách modules của NGINX bao gồm các module hỗ trợ giám sát và quản lý trạng thái, như ngx_http_stub_status_module và ngx_http_upstream_module. Việc theo dõi sức khỏe và trạng thái của backend giúp bạn nhận diện sớm các vấn đề và tối ưu lại cấu hình khi cần thiết. Trong một số trường hợp, health_check có thể được kích hoạt để có cái nhìn chi tiết về sức khỏe của từng backend trong upstream.
Kiểm tra và validation
Để đảm bảo cấu hình upstream hoạt động đúng, bạn nên thực hiện các bước kiểm tra sau:
- Kiểm tra cú pháp và hợp lệ của tập cấu hình liên quan đến upstream và proxy_pass, sau đó nạp lại NGINX khi cần. Bạn nên theo dõi log để xác định các lỗi cú pháp hoặc lỗi liên quan tới backend.
- Kiểm tra sự phân phối lưu lượng giữa các backend bằng cách gửi các yêu cầu tới các địa chỉ frontend và quan sát phản hồi. Theo dõi trạng thái trả về từ các backend và mức độ đáp ứng của từng máy chủ để điều chỉnh trọng số hoặc kết cấu liên quan.
- Đối với các khối upstream có quyền truy cập DNS, kiểm tra DNS resolution và sự thay đổi địa chỉ khi DNS thay đổi. Đảm bảo resolver được cấu hình đúng để cập nhật upstream mà không cần restart.
Checklist vận hành
- Đảm bảo upstream chứa danh sách máy chủ backend đúng và có thể đáp ứng tải.
- Kiểm tra tham số weight và backup để tối ưu phân phối tải và khả năng phục hồi.
- Xác nhận khả năng resolve cho DNS và SRV nếu bạn dựa vào cơ chế này để định danh backend.
- Theo dõi log và trạng thái của backend để phát hiện sớm sự cố và kích hoạt cơ chế failover.
Kết luận
Cấu hình NGINX Upstream để load balancing và persistence ở lớp 7 trên Ubuntu 20.04+ mang lại khả năng phân phối lưu lượng linh hoạt, khả năng mở rộng và độ sẵn sàng cao cho các ứng dụng web. Việc sử dụng các tham số như weight, max_conns, fail_timeout và backup cho upstream cho phép tùy chỉnh hành vi phân phối và phục hồi khi backend gặp sự cố. Đồng thời, khả năng resolve và service cho DNS SRV cung cấp cơ chế quản lý địa chỉ backend động mà không làm gián đoạn dịch vụ. Để đạt được hiệu quả tối ưu, hãy thiết kế cấu hình dựa trên nhu cầu thực tế, theo dõi và thử nghiệm cẩn thận trong môi trường prod.