HAProxy, viết tắt của High Availability Proxy, là một phần mềm mã nguồn mở phổ biến, chuyên dùng để cân bằng tải TCP/HTTP và proxy. Nó có thể hoạt động trên các hệ điều hành Linux, macOS và FreeBSD.

Mục đích chính của HAProxy là cải thiện hiệu suất và độ tin cậy của môi trường máy chủ bằng cách phân phối khối lượng công việc đến nhiều máy chủ khác nhau (ví dụ: máy chủ web, máy chủ ứng dụng hoặc cơ sở dữ liệu). HAProxy được triển khai trong nhiều hệ thống quy mô lớn và có mức độ nhận diện cao, bao gồm GitHub, Imgur, Instagram và Twitter.
Trong bài hướng dẫn này, chúng ta sẽ cùng tìm hiểu:
- Tổng quan về HAProxy là gì.
- Các thuật ngữ liên quan đến cân bằng tải.
- Các ví dụ về cách HAProxy có thể được sử dụng để cải thiện hiệu suất và độ tin cậy cho môi trường máy chủ của bạn.
Thuật ngữ trong HAProxy
Có nhiều thuật ngữ và khái niệm quan trọng cần nắm khi thảo luận về cân bằng tải và proxy. Bạn sẽ tìm hiểu các thuật ngữ thường dùng trong những phần sau đây.
Trước khi đi vào các loại cân bằng tải cơ bản, chúng ta sẽ bắt đầu tìm hiểu về ACL, backend và frontend.
Access Control List (ACL)
Trong ngữ cảnh cân bằng tải, ACL được dùng để kiểm tra một điều kiện nào đó và thực hiện một hành động dựa trên kết quả kiểm tra (ví dụ: chọn máy chủ, chặn yêu cầu…). Việc sử dụng ACL cho phép định tuyến lưu lượng mạng một cách linh hoạt dựa trên nhiều yếu tố như khớp mẫu đường dẫn, số lượng kết nối đến backend…
Ví dụ về một ACL:
acl url_blog path_beg /blog
ACL này sẽ được áp dụng nếu đường dẫn trong yêu cầu của người dùng bắt đầu bằng /blog. Chẳng hạn, yêu cầu tới http://yourdomain.com/blog/blog-entry-1 sẽ phù hợp với ACL này.
Để biết thêm hướng dẫn chi tiết về cách sử dụng ACL, hãy tham khảo Tài liệu cấu hình HAProxy.
Backend
Backend là tập hợp các máy chủ nhận yêu cầu được chuyển tiếp đến. Các backend được khai báo trong phần backend của tệp cấu hình HAProxy. Ở dạng đơn giản nhất, một backend có thể được định nghĩa bởi:
- thuật toán cân bằng tải sẽ sử dụng
- danh sách các máy chủ và cổng kết nối
Một backend có thể bao gồm một hoặc nhiều máy chủ. Nhìn chung, việc thêm nhiều máy chủ vào backend sẽ giúp tăng khả năng xử lý tải nhờ cơ chế phân phối lưu lượng giữa các máy chủ. Đồng thời, điều này cũng cải thiện độ tin cậy của hệ thống trong trường hợp một hoặc vài máy chủ backend không còn khả dụng.
Dưới đây là ví dụ về cấu hình hai backend, web-backend và blog-backend, mỗi backend có hai máy chủ web lắng nghe trên cổng 80:
backend web-backend
balance roundrobin
server web1 web1.yourdomain.com:80 check
server web2 web2.yourdomain.com:80 check
backend blog-backend
balance roundrobin
mode http
server blog1 blog1.yourdomain.com:80 check
server blog1 blog1.yourdomain.com:80 check
Dòng balance roundrobin chỉ định thuật toán cân bằng tải được sử dụng, chi tiết sẽ được trình bày trong phần Thuật toán cân bằng tải.
Dòng mode http xác định rằng proxy tầng 7 (layer 7) sẽ được sử dụng. Điều này sẽ được giải thích rõ hơn trong phần Các loại Cân bằng tải.
Tùy chọn check ở cuối mỗi dòng server nghĩa là HAProxy sẽ tự động đánh giá tình trạng hoạt động của các máy chủ backend đó.
Frontend
Frontend xác định cách các yêu cầu được chuyển tiếp đến các backend. Các frontend được khai báo trong phần frontend của tệp cấu hình HAProxy, với nội dung bao gồm các yếu tố sau:
- một tập hợp địa chỉ IP và cổng (ví dụ: 10.1.1.7:80, *:443…)
- các ACL
- các quy tắc
use_backend, quy định backend nào sẽ được sử dụng tùy theo điều kiện ACL được khớp, và/hoặc một quy tắcdefault_backendxử lý tất cả các trường hợp còn lại
Frontend có thể được cấu hình để xử lý nhiều loại lưu lượng mạng khác nhau. Nội dung chi tiết sẽ được trình bày trong phần tiếp theo.
Các loại cân bằng tải
Sau khi nắm được các thành phần cơ bản được sử dụng trong cơ chế cân bằng tải, bước kế đến chúng ta sẽ cùng tìm hiểu về các loại cân bằng tải phổ biến.
Không sử dụng cân bằng tải
Một môi trường ứng dụng web đơn giản, không có cơ chế cân bằng tải, có thể trông như sau:

Trong ví dụ này, người dùng kết nối trực tiếp đến máy chủ web tại địa chỉ yourdomain.com mà không thông qua bất kỳ tầng cân bằng tải nào. Nếu máy chủ duy nhất này gặp sự cố, người dùng sẽ không thể truy cập vào trang web. Ngoài ra, nếu có quá nhiều người dùng truy cập đồng thời và máy chủ không đủ khả năng xử lý tải thì trang web có thể phản hồi chậm hoặc người dùng có thể không kết nối được.
Cân bằng tải tầng 4
Cách đơn giản nhất để phân phối lưu lượng mạng đến nhiều máy chủ là sử dụng cân bằng tải ở tầng 4 (tầng vận chuyển). Ở phương pháp này, lưu lượng người dùng sẽ được chuyển tiếp dựa trên dải IP và cổng (nghĩa là nếu có yêu cầu gửi đến địa chỉ http://yourdomain.com/anything, thì lưu lượng đó sẽ được chuyển đến backend phụ trách toàn bộ các yêu cầu đến yourdomain.com trên cổng 80). Để hiểu rõ hơn về tầng 4, bạn hãy tham khảo phần TCP trong tài liệu “Giới thiệu về Mạng máy tính”.
Dưới đây là sơ đồ minh họa một ví dụ đơn giản về cân bằng tải tầng 4:

Khi người dùng truy cập vào bộ cân bằng tải, thành phần này sẽ chuyển tiếp yêu cầu đến nhóm máy chủ backend có tên là web-backend. Máy chủ backend nào được chọn sẽ trực tiếp phản hồi lại yêu cầu của người dùng. Về nguyên tắc, tất cả các máy chủ trong nhóm web-backend sẽ cung cấp nội dung giống nhau, nếu không, người dùng có thể nhận được nội dung không nhất quán. Lưu ý rằng cả hai máy chủ web đều kết nối tới cùng một máy chủ cơ sở dữ liệu.
Cân bằng tải tầng 7
Một phương pháp phức tạp hơn để cân bằng tải lưu lượng mạng là sử dụng cân bằng tải ở tầng 7 (tầng ứng dụng). Phương pháp này cho phép load balancer chuyển tiếp các yêu cầu đến các máy chủ backend khác nhau dựa trên nội dung của yêu cầu từ phía người dùng. Chế độ cân bằng tải này cho phép bạn vận hành nhiều máy chủ ứng dụng web dưới cùng một tên miền và cổng. Để biết thêm chi tiết về tầng 7, bạn hãy tham khảo phần HTTP trong tài liệu “Giới thiệu về Mạng máy tính”.
Dưới đây là sơ đồ minh họa một ví dụ đơn giản về cân bằng tải tầng 7:

Trong ví dụ này, nếu người dùng yêu cầu truy cập yourdomain.com/blog, họ sẽ được chuyển tiếp đến blog-backend, một tập hợp các máy chủ chạy ứng dụng blog. Các yêu cầu khác sẽ được chuyển đến web-backend, nơi có thể đang vận hành một ứng dụng khác. Cả hai backend trong ví dụ này đều sử dụng chung một máy chủ cơ sở dữ liệu.
Một đoạn cấu hình frontend ví dụ sẽ có dạng như sau:
frontend http
bind *:80
mode http
acl url_blog path_beg /blog
use_backend blog-backend if url_blog
default_backend web-backend
Cấu hình này định nghĩa một frontend có tên là http, xử lý toàn bộ lưu lượng đến trên cổng 80.
Dòng acl url_blog path_beg /blog sẽ khớp với các yêu cầu có đường dẫn bắt đầu bằng /blog.
Dòng use_backend blog-backend if url_blog sử dụng ACL vừa định nghĩa để chuyển tiếp lưu lượng đến blog-backend.
Dòng default_backend web-backend chỉ định mọi lưu lượng không khớp với ACL sẽ được chuyển tiếp đến web-backend.
Các thuật toán cân bằng tải
Thuật toán cân bằng tải được sử dụng quyết định máy chủ nào trong một backend sẽ được chọn khi thực hiện cân bằng tải. HAProxy cung cấp một số lựa chọn cho thuật toán cân bằng tải. Bên cạnh thuật toán cân bằng tải, các máy chủ còn có thể được gán tham số trọng số để điều chỉnh tần suất mà máy chủ được chọn, so với các máy chủ khác.
Dưới đây là một số thuật toán thường được sử dụng:
roundrobin
Round Robin chọn các máy chủ theo kiểu luân phiên. Đây là thuật toán mặc định.
leastconn
Chọn máy chủ có ít kết nối nhất. Thuật toán này được khuyến khích sử dụng cho các phiên làm việc kéo dài. Các máy chủ trong cùng một backend cũng sẽ được chọn theo kiểu luân phiên.
source
Thuật toán này chọn máy chủ dựa trên băm của địa chỉ IP nguồn mà người dùng đang sử dụng để gửi yêu cầu. Phương pháp này đảm bảo rằng những người dùng cùng một địa chỉ IP sẽ luôn kết nối với cùng một máy chủ.
Phiên làm việc cố định (Sticky Sessions)
Một số ứng dụng yêu cầu người dùng phải tiếp tục kết nối với cùng một máy chủ backend. Điều này có thể được thực hiện thông qua các phiên sticky, sử dụng tham số appsession trong backend để yêu cầu tính năng này.
Tự động kiểm tra tình trạng (Health Check)
HAProxy sử dụng cơ chế kiểm tra tình trạng tự động để xác định một máy chủ backend có sẵn sàng xử lý yêu cầu hay không. Nhờ đó, bạn không cần phải loại bỏ thủ công các máy chủ không còn khả dụng khỏi backend. Theo mặc định, quá trình kiểm tra này được thự hiện bằng cách cố gắng thiết lập kết nối TCP đến máy chủ.
Nếu một máy chủ không vượt qua được kiểm tra tình trạng và không còn khả năng phục vụ yêu cầu, máy chủ đó sẽ tự động bị vô hiệu hóa trong backend. Lưu lượng sẽ không được chuyển đến máy chủ này cho đến khi nó hoạt động bình thường trở lại. Trong trường hợp tất cả máy chủ trong một backend đều gặp sự cố, dịch vụ tương ứng sẽ không khả dụng cho đến khi ít nhất một máy chủ trong nhóm đó phục hồi.
Đối với một số loại backend, như các máy chủ cơ sở dữ liệu, kiểm tra tình trạng mặc định không nhất thiết phải kiểm tra xem máy chủ có còn hoạt động bình thường hay không.
Máy chủ web Nginx cũng có thể được sử dụng như một máy chủ proxy độc lập hoặc load balancer, và thường được kết hợp với HAProxy nhờ vào khả năng caching và nén của nó.
Độ sẵn sàng cao (High Availability)
Các cấu hình cân bằng tải tầng 4 và tầng 7 được trình bày trong hướng dẫn này đều sử dụng một load balancer để phân phối lưu lượng đến một trong nhiều máy chủ backend. Tuy nhiên, trong các cấu hình như vậy, load balancer trở thành một điểm lỗi đơn. Nếu gặp sự cố hoặc bị quá tải với các yêu cầu, nó có thể gây ra độ trễ cao hoặc làm gián đoạn dịch vụ.
Một cấu hình high availability (HA), hay còn gọi là cấu hình có độ sẵn sàng cao, được hiểu rộng là một hệ thống hạ tầng không có điểm lỗi đơn. Mục tiêu của cấu hình này là ngăn chặn việc một máy chủ bị lỗi có thể gây ra downtime cho toàn bộ hệ thống, bằng cách bổ sung tính dự phòng (redundancy) vào mọi tầng trong kiến trúc.
Load balancer giúp đảm bảo tính dự phòng cho tầng backend (gồm các máy chủ web/ứng dụng), nhưng để đạt được cấu hình HA thực sự, chính bản thân các load balancer cũng cần được triển khai theo mô hình dự phòng.
Dưới đây là sơ đồ minh họa một cấu hình độ sẵn sàng cao:
Trong ví dụ này, bạn có nhiều load balancer (một hoạt động và một hoặc nhiều ở trạng thái chờ) nằm phía sau một địa chỉ IP tĩnh, có thể được ánh xạ lại giữa các máy chủ. Khi người dùng truy cập vào trang web của bạn, yêu cầu sẽ đi qua địa chỉ IP bên ngoài và được chuyển tiếp đến load balancer đang hoạt động. Nếu load balancer này gặp sự cố, cơ chế chuyển đổi dự phòng (failover) sẽ phát hiện ra và tự động gán lại địa chỉ IP cho một trong các máy chủ ở trạng thái chờ. Có nhiều cách khác nhau để triển khai một cấu hình độ khả dụng cao (HA) theo mô hình hoạt động/chờ.
Kết luận
Giờ đây, khi bạn đã nắm được kiến thức về cân bằng tải và biết cách sử dụng HAProxy, bạn đã có nền tảng vững chắc để bắt đầu cải thiện hiệu suất và độ tin cậy cho môi trường máy chủ của riêng mình.