0

Load Balancer toàn tập: bí mật đằng sau các hệ thống triệu traffic

Hãy tưởng tượng ứng dụng của bạn vừa tạo nên một cơn sốt. Lượng người dùng (traffic) đột ngột đổ về hàng triệu lượt chỉ trong vài phút. Nếu toàn bộ con số khổng lồ này đâm sầm vào một máy chủ (server) duy nhất, hệ thống sẽ ngay lập tức "đóng băng", kéo theo doanh thu và trải nghiệm khách hàng chạm đáy.

Thế nhưng, các nền tảng công nghệ lớn gần như không bao giờ để thảm họa đó xảy ra. Bí mật đằng sau khả năng gánh vác triệu traffic không nằm ở việc sở hữu một siêu máy tính đắt tiền, mà nằm ở một "người nhạc trưởng" thầm lặng đứng ra điều phối toàn bộ luồng dữ liệu: Load Balancer (Bộ cân bằng tải).

Bài viết này sẽ là cẩm nang toàn tập giúp bạn giải mã trọn vẹn "người nhạc trưởng" đó. Chúng ta sẽ cùng mổ xẻ mọi ngóc ngách kiến trúc: từ các thuật toán "chia bài" cốt lõi, cách phân luồng thông minh ở Tầng 4 và Tầng 7, cho đến nghệ thuật tự động mở rộng (auto-scaling) để sống sót qua những đợt bùng nổ traffic lớn nhất. Đã đến lúc hệ thống hóa lại tư duy thiết kế và làm chủ mảnh ghép sống còn này!

Bạn đã sẵn sàng để chúng ta bắt tay vào viết chi tiết chưa?

Phần 1: Các thuật toán phân phối (Algorithms)

Trạm dừng chân đầu tiên của chúng ta là: Các Thuật Toán Cân Bằng Tải (Load Balancing Algorithms).

Trước khi đi sâu vào mạng lưới phức tạp, chúng ta cần hiểu "logic" mà Load Balancer (LB) dùng để quyết định: "Request này sẽ được giao cho ai?".

Dưới đây là 3 thuật toán phổ biến nhất, từ đơn giản đến thông minh:

  • 🔄 Round Robin (Luân phiên): Hãy tưởng tượng bạn đang chia bài. Lá thứ 1 cho Server A, lá thứ 2 cho Server B, lá thứ 3 cho Server C, rồi quay vòng lại A.

    • Ưu điểm: Cực kỳ đơn giản, công bằng.

    • Nhược điểm: LB "bị mù" về trạng thái thực tế. Nó không biết Server A đang quá tải còn Server B thì đang rảnh rỗi.

  • ⚖️ Least Connections (Ít kết nối nhất): Khôn ngoan hơn Round Robin. LB sẽ đếm số lượng kết nối đang mở (active connections) của từng server. Khi có request mới, nó sẽ quẳng cho server đang rảnh việc nhất. Rất hiệu quả khi hệ thống có những request cần thời gian xử lý dài ngắn khác nhau.

  • 📌 IP Hash (Băm IP): Thuật toán này lấy địa chỉ IP của người dùng làm đầu vào để tính toán (hash) ra một con số, từ đó chỉ định server. Điều này đảm bảo: Một người dùng cụ thể sẽ luôn luôn được kết nối tới cùng một server (trừ khi server đó chết). Rất hữu ích để giữ phiên đăng nhập (session) hoặc giỏ hàng của người dùng.

Hãy thử tưởng tượng một tình huống thực tế: Hệ thống của bạn có Server A là một chiếc máy chủ vật lý đời mới cực mạnh, còn Server B và C là những máy chủ ảo cũ hơn, năng lực xử lý chỉ bằng một nửa Server A.

Nếu chúng ta áp dụng thuật toán Round Robin cơ bản, Server A sẽ chơi dài trong khi B và C có thể bị quá tải. Theo bạn, người ta đã nâng cấp thuật toán Round Robin như thế nào để giải quyết sự "lệch pha" về phần cứng này?

Đây là một bài toán rất thực tế mà bất kỳ hệ thống lớn nào cũng gặp phải. Để giải quyết sự "lệch pha" về phần cứng, các kỹ sư đã bổ sung thêm một "gia vị" rất quan trọng vào thuật toán: Trọng số (Weight).

Từ đó, chúng ta có phiên bản nâng cấp: Weighted Round Robin (Luân phiên có trọng số).

Cách hoạt động của nó cực kỳ logic. Thay vì Load Balancer chia đều tăm tắp 1-1-1, bạn có thể cấu hình (khai báo) cho nó biết sức mạnh của từng máy chủ:

  • Server A (Máy xịn): Trọng số = 2
  • Server B (Máy cũ): Trọng số = 1
  • Server C (Máy cũ): Trọng số = 1

Khi có 4 request mới đổ về, Load Balancer sẽ chia theo tỷ lệ trọng số này: A -> A -> B -> C. Nhờ vậy, Server A tận dụng tối đa năng lực, còn B và C thì không bị quá tải đứt gánh. Tương tự, hệ thống cũng có Weighted Least Connections, kết hợp việc đếm số kết nối hiện tại và so sánh với sức tải tối đa của máy chủ để điều hướng.

Phần 2: Phân loại Load Balancer (Layer 4 vs. Layer 7)

Bây giờ chúng ta đã biết Load Balancer dùng "logic" gì để chia việc. Tiếp theo, chúng ta cần tìm hiểu xem nó dựa vào thông tin gì của gói tin để đưa ra quyết định. Trong mạng máy tính (theo mô hình OSI), người ta thường chia Load Balancer làm 2 loại chính:

  • Layer 4 Load Balancer (Tầng Giao vận - Transport): Bạn hãy tưởng tượng nó giống như một nhân viên phân loại thư bưu điện. Nhân viên này làm việc cực kỳ nhanh, nhưng anh ta chỉ được phép nhìn vào vỏ phong bì để xem địa chỉ IP và Cổng (Port). Anh ta không hề biết bên trong thư viết gì.

  • Layer 7 Load Balancer (Tầng Ứng dụng - Application): Nó giống như một người trợ lý giám đốc. Người này có quyền "bóc thư" ra để đọc nội dung bên trong. Nó hiểu được ngôn ngữ HTTP, biết chính xác người dùng đang truy cập đường dẫn (URL) nào, có mang theo Cookie gì không, và đang dùng điện thoại hay máy tính. Đổi lại, vì phải "đọc" nhiều hơn nên tốc độ xử lý của nó sẽ chậm hơn Layer 4 một chút.

Tôi có một câu hỏi tình huống cho bạn: Giả sử hệ thống thương mại điện tử của bạn vừa ra mắt tính năng xem Video Review. Bạn đã đầu tư một cụm Server cực mạnh chỉ chuyên dùng để stream video. Bạn muốn cấu hình Load Balancer sao cho: "Cứ request nào gọi vào đường dẫn có chứa /video (ví dụ: website.com/video) thì đẩy hết sang cụm Server mới này".

Theo bạn, để làm được việc bóc tách đường dẫn này, chúng ta bắt buộc phải dùng Layer 4 hay Layer 7? Và tại sao?

Chìa khóa để giải quyết bài toán này nằm ở mức độ chi tiết của gói tin mà chúng ta muốn đọc. Để điều hướng dựa trên đường dẫn /video, chúng ta bắt buộc phải dùng Layer 7 Load Balancer.

Tại sao lại như vậy?

  • Giới hạn của Layer 4: Nhớ lại ví dụ về người nhân viên bưu điện, Layer 4 chỉ làm việc với "vỏ phong bì" – tức là Địa chỉ IP và Cổng mạng (ví dụ: request gửi đến IP 203.0.113.1, cổng 443 cho HTTPS). Nó hoàn toàn không thể thấy phần đuôi /video.

  • Sức mạnh của Layer 7: Load Balancer ở tầng 7 giao tiếp bằng ngôn ngữ HTTP. Nhờ đó, nó "bóc" gói tin ra và đọc được toàn bộ HTTP URL (chứa phần /video), cũng như các thẻ Header hay Cookie.

Kỹ thuật này trong thực tế được gọi là Path-based Routing (Định tuyến dựa trên đường dẫn). Bạn có thể có hàng chục đường dẫn khác nhau (/video, /payment, /user-profile) trỏ về các cụm máy chủ chuyên biệt riêng lẻ, và tất cả đều được phân luồng mượt mà thông qua một Layer 7 Load Balancer duy nhất.

Phần 3: Health Check (Kiểm tra sức khỏe)

Bây giờ chúng ta sẽ chuyển sang một khía cạnh sống còn khác của Load Balancer: duy trì tính sẵn sàng cao (High Availability) cho hệ thống.

Giả sử Load Balancer của bạn đang chia đều công việc cho 3 Server: A, B, và C. Đột nhiên, ổ cứng của Server B gặp sự cố hoặc ứng dụng trên đó bị "treo". Nếu Load Balancer không nhận thức được điều này, nó vẫn sẽ gửi request của người dùng vào Server B, dẫn đến việc người dùng nhận được màn hình báo lỗi chớp nhoáng (ví dụ như lỗi 502 Bad Gateway hay 504 Gateway Timeout).

Để ngăn chặn thảm họa này, Load Balancer sử dụng một cơ chế gọi là Health Check để liên tục giám sát các server.

Theo bạn, Load Balancer có thể thực hiện những hành động cụ thể nào để "bắt mạch" định kỳ, nhằm xác định xem Server B còn khả năng phục vụ người dùng hay không?

Cách Load Balancer "bắt mạch" thực chất rất giống với việc bạn mở trình duyệt và tải lại (F5) một trang web để xem nó còn hoạt động hay không. Cơ chế tự động này được chia làm hai cấp độ, tương ứng với Tầng 4 và Tầng 7 mà chúng ta vừa phân tích:

  • 🩺 Kiểm tra Tầng 4 (TCP Check): Load Balancer chỉ đơn giản là "gõ cửa" cổng mạng của máy chủ (ví dụ: cổng 80 cho web). Nếu máy chủ "mở cửa" (chấp nhận kết nối TCP), nó được coi là khỏe mạnh.

    • Vấn đề ở đây là: Đôi khi cổng mạng vẫn mở, nhưng bản thân phần mềm web bên trong lại đang bị treo và trả về màn hình trắng xóa. TCP Check không thể phát hiện ra điều này.
  • 🔬 Kiểm tra Tầng 7 (HTTP Check): Đây là cách khám bệnh chuyên sâu và an toàn nhất. Load Balancer sẽ gửi một yêu cầu HTTP thực sự (ví dụ: truy cập vào đường dẫn website.com/health_status). Máy chủ bắt buộc phải trả về mã trạng thái 200 OK (hoặc một từ khóa cụ thể do bạn quy định). Nếu máy chủ trả lời chậm quá thời gian cho phép (timeout) hoặc báo lỗi 500 Internal Server Error, Load Balancer sẽ lập tức dán nhãn "Unhealthy" (Không khỏe).

Khi một máy chủ bị đánh dấu "Unhealthy", Load Balancer sẽ tự động rút nó ra khỏi hàng đợi và không gửi thêm bất kỳ request nào vào đó nữa. Nó vẫn sẽ tiếp tục "khám bệnh" ngầm, cho đến khi máy chủ này trả lời 200 OK trở lại 3 lần liên tiếp (tùy cấu hình) thì mới được đưa lại vào hàng đợi để làm việc.

Một khía cạnh sống còn khác: Sự cố của chính Load Balancer (SPOF)

Nếu Load Balancer đứng ra bảo vệ các Server, vậy ai sẽ bảo vệ Load Balancer? Nếu chiếc Load Balancer duy nhất này bị rút điện, toàn bộ hệ thống sẽ sập, bất kể bạn có bao nhiêu máy chủ bên dưới. Đây gọi là Điểm lỗi duy nhất (Single Point of Failure - SPOF).

Để giải quyết, người ta không bao giờ dùng 1 Load Balancer đơn độc trong hệ thống lớn, mà dùng theo cặp (thường là mô hình Active-Passive). Cả hai chiếc Load Balancer sẽ dùng chung một Địa chỉ IP Ảo (Virtual IP). Khách hàng chỉ gọi vào IP Ảo này. Chiếc Active sẽ làm việc chính, chiếc Passive đứng quan sát. Nếu chiếc Active chết, chiếc Passive sẽ chớp nhoáng cướp lấy IP Ảo và thế chỗ ngay lập tức (thường trong vòng chưa tới 1 giây).

Phần 4: SSL Termination (Xử lý mã hóa)

Ngày nay, gần như 100% các website đều dùng HTTPS (dữ liệu được mã hóa) thay vì HTTP (dữ liệu văn bản thô). Việc giải mã dữ liệu HTTPS đòi hỏi máy tính phải tiêu tốn rất nhiều năng lực CPU.

Khi một luồng dữ liệu bị mã hóa HTTPS đi từ người dùng đến hệ thống của bạn, hệ thống buộc phải giải mã nó thì mới đọc được nội dung (như đọc URL ở Layer 7). Theo bạn, chúng ta nên cấu hình để Load Balancer tự đứng ra giải mã toàn bộ dữ liệu này, hay Load Balancer chỉ nên làm "người đưa thư" và nhường việc giải mã cho các Server bên dưới? Mọi cách tiếp cận đều có ưu/nhược điểm riêng của nó.

Đây là một bài toán đánh đổi rất kinh điển trong thiết kế hệ thống. Mỗi phương án đều có ưu và nhược điểm riêng, tương ứng với hai khái niệm: SSL Termination (Giải mã tại Load Balancer) và SSL Passthrough (Chuyển tiếp nguyên bản).

Chúng ta cùng mổ xẻ chi tiết hai phương pháp này nhé:

1. Khái niệm cốt lõi

  • 🔓 SSL Termination (Giải mã tại cửa): Load Balancer sẽ giữ chìa khóa bảo mật (Chứng chỉ SSL). Khi gói tin HTTPS đến, Load Balancer sẽ giải mã nó thành HTTP văn bản thô, đọc nội dung, rồi gửi gói tin HTTP đó đến các Server bên dưới.

  • 🔒 SSL Passthrough (Chuyển tiếp nguyên bản): Load Balancer đóng vai trò "người vận chuyển" mù quáng. Nó nhận gói tin HTTPS đang bị khóa chặt và ném thẳng gói tin đó cho các Server bên dưới. Các Server này tự giữ chìa khóa và tự giải mã.

2. So sánh ưu và nhược điểm

Tiêu chí 🔓 SSL Termination 🔒 SSL Passthrough
Giảm tải cho Server Tốt. Server bên dưới rảnh rang, chỉ tập trung xử lý logic ứng dụng. Kém. Các Server phải tự giải mã, tốn rất nhiều CPU.
Tính năng Layer 7 Có. Load Balancer đọc được dữ liệu nên có thể chia tải theo đường dẫn (URL), Cookie... Không. Load Balancer không đọc được nội dung bên trong nên chỉ có thể làm Layer 4.
Giảm tải cho Server Dễ dàng. Chỉ cần cài đặt chứng chỉ SSL duy nhất trên Load Balancer. Kém. Các Server phải tự giải mã, tốn rất nhiều CPU.
Quản lý Chứng chỉ Tốt. Server bên dưới rảnh rang, chỉ tập trung xử lý logic ứng dụng. Kém. Các Server phải tự giải mã, tốn rất nhiều CPU.
Bảo mật nội bộ Thấp hơn. Dữ liệu truyền từ Load Balancer đến Server là dạng thô (HTTP). Chỉ an toàn nếu dùng mạng nội bộ (VPC) khép kín. Tối đa (End-to-end). Dữ liệu được mã hóa suốt từ máy người dùng đến tận Server.

Trong thực tế, SSL Termination được sử dụng phổ biến nhất vì nó giúp quản lý chứng chỉ nhàn hạ hơn rất nhiều và cho phép dùng Layer 7 Load Balancer. Chỉ những hệ thống đòi hỏi bảo mật cực kỳ khắt khe (như ngân hàng, y tế) mới yêu cầu mã hóa toàn trình và dùng SSL Passthrough.

Chúng ta đã đi một chặng đường khá dài qua các khía cạnh cốt lõi của Load Balancer:

  1. Thuật toán phân phối (Round Robin, Least Connections...)
  2. Tầng xử lý (Layer 4 vs Layer 7)
  3. Sức khỏe hệ thống (Health Check & SPOF)
  4. Xử lý bảo mật (SSL)

Để tổng hợp lại những gì chúng ta vừa trao đổi, tôi có một tình huống thiết kế thực tế dành cho bạn:

Giả sử bạn đang xây dựng ứng dụng ngân hàng. Bạn có 2 cụm máy chủ: Cụm A xử lý website.com/thong-tin và cụm B (chứa dữ liệu nhạy cảm) xử lý website.com/chuyen-tien. Quy định bảo mật bắt buộc dữ liệu chuyển tiền phải được mã hóa mã hóa 100% từ máy khách hàng đến tận máy chủ xử lý (End-to-End).

Với yêu cầu này, bạn sẽ kết hợp các cấu hình (Tầng 4 hay 7, SSL Termination hay Passthrough) như thế nào cho hệ thống Load Balancer của mình?

⏯️Tình huống này thực chất là một bài toán mâu thuẫn kinh điển trong thiết kế hệ thống! Khi thiết kế, chúng ta đang gặp phải hai yêu cầu "đá" nhau:

  1. Để đọc được đường dẫn /chuyen-tien, chúng ta bắt buộc phải dùng Layer 7 và bóc gói tin ra (SSL Termination).

  2. Để mã hóa toàn trình (End-to-End) sao cho Load Balancer hoàn toàn không đọc được dữ liệu nhạy cảm, chúng ta buộc phải dùng Layer 4 (SSL Passthrough).

Bạn không thể vừa "bịt mắt" (Passthrough) lại vừa muốn "đọc chữ" (Layer 7). Để giải quyết bài toán này, các kỹ sư hệ thống thường dùng 2 chiến thuật sau:

  • 🛡️ Chiến thuật 1: Mã hóa lại (SSL Bridging / Re-encryption): Load Balancer vẫn hoạt động ở Layer 7. Nó sẽ giải mã gói tin từ người dùng (để đọc đường dẫn /chuyen-tien). Ngay sau khi biết cần chuyển đi đâu, nó lập tức mã hóa gói tin đó lại thành một luồng HTTPS mới rồi mới gửi đến Cụm B. Dữ liệu trên đường truyền nội bộ vẫn an toàn, nhưng Load Balancer (trong một tích tắc) có quyền truy cập dữ liệu.

  • 🏰 Chiến thuật 2: Đổi kiến trúc - Dùng Tên miền phụ (Subdomain): Đây là cách bảo mật tuyệt đối. Thay vì dùng đường dẫn, ngân hàng sẽ tách ứng dụng ra làm hai tên miền: info.website.compay.website.com. Khi đó, Load Balancer hoạt động ở Layer 4. Nó sử dụng một tính năng gọi là SNI (đọc tên miền đích được in ngay trên "vỏ phong bì" mạng) để điều hướng thẳng gói tin pay.website.com sang cụm B thông qua SSL Passthrough. Cụm B sẽ tự cầm chìa khóa để giải mã.

Phần 5: Sticky Session (Phiên gắn kết)

Chúng ta đã giải quyết xong bài toán phân luồng và bảo mật. Bây giờ, hãy nói về trải nghiệm của người dùng.

Hãy tưởng tượng bạn đang mua sắm trực tuyến. Hệ thống có 3 Server (A, B, C) chạy thuật toán Round Robin.

  1. Bạn đăng nhập thành công. Lượt của bạn rơi vào Server A. Server A ghi nhớ bạn đã đăng nhập.
  2. Bạn bấm thêm một chiếc áo vào giỏ hàng. Lần này Load Balancer chuyển request sang Server B.
  3. Server B không hề biết bạn là ai (vì thông tin đăng nhập đang nằm ở Server A). Thế là nó đẩy bạn văng ra ngoài màn hình bắt đăng nhập lại.

Sự cố này xảy ra vì HTTP là một giao thức "không trạng thái" (stateless) - mỗi request là một giao dịch hoàn toàn độc lập. Thuật toán IP Hash (băm IP) có thể giải quyết việc này vì nó ghim cứng 1 IP với 1 Server, nhưng nếu hàng nghìn nhân viên trong cùng một công ty (dùng chung 1 IP mạng) cùng truy cập, thuật toán IP Hash sẽ đẩy toàn bộ tải vào 1 Server duy nhất gây quá tải.

Câu hỏi dành cho bạn là Nếu chúng ta đang sử dụng Load Balancer Tầng 7, Load Balancer có thể sử dụng "công cụ" gì của trình duyệt web để "đánh dấu" người dùng, đảm bảo rằng anh ta đi đâu thì những request tiếp theo của anh ta cũng bị "nam châm" hút về lại đúng Server A?

Sự cố này xảy ra vì HTTP là một giao thức "không trạng thái" (stateless) - mỗi request là một giao dịch hoàn toàn độc lập. Thuật toán IP Hash (băm IP) có thể giải quyết việc này vì nó ghim cứng 1 IP với 1 Server, nhưng nếu hàng nghìn nhân viên trong cùng một công ty (dùng chung 1 IP mạng) cùng truy cập, thuật toán IP Hash sẽ đẩy toàn bộ tải vào 1 Server duy nhất gây quá tải.

Câu hỏi dành cho bạn: Nếu chúng ta đang sử dụng Load Balancer Tầng 7, Load Balancer có thể sử dụng "công cụ" gì của trình duyệt web để "đánh dấu" người dùng, đảm bảo rằng anh ta đi đâu thì những request tiếp theo của anh ta cũng bị "nam châm" hút về lại đúng Server A?

Công cụ tuyệt vời mà bạn đang nhắc đến chính là Cookie 🍪. Khi hoạt động ở Tầng 7 (Application), Load Balancer (LB) có toàn quyền đọc và ghi vào dữ liệu HTTP, cho phép nó triển khai một cơ chế rất thông minh gọi là Sticky Sessions (Phiên gắn kết) hoặc Session Affinity.

Cách thức hoạt động của nó diễn ra theo các bước cực kỳ logic:

  1. Lần đầu gặp gỡ: Khi bạn gửi yêu cầu đăng nhập, trình duyệt chưa có thông tin gì. LB sẽ dùng thuật toán cơ bản (như Round Robin) để chọn một máy chủ, giả sử là Server A.

  2. Phát "phù hiệu": Sau khi Server A xử lý xong, LB sẽ bí mật "nhét" một Cookie đặc biệt vào phản hồi gửi trả về trình duyệt (ví dụ: SERVERID=Server_A).

  3. Nhận diện người quen: Ở các yêu cầu tiếp theo (như khi bạn bấm thêm hàng vào giỏ), trình duyệt sẽ tự động gửi kèm chiếc Cookie SERVERID=Server_A đó lên. LB đọc được chiếc Cookie này, nhận ra ngay "người quen của Server A" và lập tức chuyển thẳng yêu cầu vào Server A mà không cần tính toán lại.

Sticky Session bằng Cookie giải quyết được bài toán giữ phiên đăng nhập rất tốt mà không bị phụ thuộc vào địa chỉ IP của khách hàng.

Tuy nhiên, hãy thử suy nghĩ về một tình huống bất ngờ: Nếu Server A đột ngột bị sập (chết phần cứng hoặc mất mạng), điều gì sẽ xảy ra với những người dùng đang bị "ghim" vào Server A đó? Theo bạn, Load Balancer sẽ xử lý thế nào và trải nghiệm của người dùng lúc đó sẽ bị ảnh hưởng ra sao?

Khi Server A đột ngột "bốc hơi", đây chính là lúc các cơ chế mà chúng ta đã tìm hiểu từ đầu đến giờ bắt đầu phối hợp với nhau. Dưới đây là bức tranh chi tiết về những gì sẽ diễn ra:

1. Phản ứng của Load Balancer

Nhờ có cơ chế Health Check (Kiểm tra sức khỏe) chạy ngầm liên tục, Load Balancer sẽ nhanh chóng phát hiện ra Server A không còn phản hồi (ví dụ: không trả về mã 200 OK).

Ngay lập tức, Load Balancer gạch tên Server A khỏi danh sách hoạt động. Khi người dùng (đang có Cookie gắn với Server A) gửi request tiếp theo (ví dụ: bấm thanh toán), Load Balancer thấy Server A đã chết, nó đành phải "chữa cháy" bằng cách dùng thuật toán Round Robin đẩy request này sang Server B (hoặc C).

2. Trải nghiệm của người dùng (Sự cố mất phiên)

Lúc này, rắc rối thực sự mới xuất hiện. Trình duyệt của người dùng mang Cookie và giỏ hàng đến gõ cửa Server B. Nhưng Server B hoàn toàn "ngơ ngác" vì mọi thông tin đăng nhập và giỏ hàng của người dùng đó từ nãy đến giờ đều được lưu trên bộ nhớ RAM của Server A.

Kết quả: Người dùng đang mua hàng bỗng nhiên bị văng ra màn hình đăng nhập, hoặc giỏ hàng trống trơn. Trải nghiệm vô cùng tồi tệ.

3. Giải pháp thực tế của các hệ thống lớn

Để giải quyết nhược điểm chí mạng này của Sticky Session, các hệ thống lớn hiện đại thường không lưu dữ liệu phiên làm việc trên từng Server riêng lẻ nữa. Thay vào đó, họ xây dựng một trạm lưu trữ bộ nhớ đệm tập trung ở bên ngoài (thường dùng các công cụ như Redis hoặc Memcached).

Quy trình lúc này sẽ thay đổi:

  • Bất kể Load Balancer đẩy người dùng vào Server A, B hay C, các Server này đều không tự nhớ thông tin.

  • Chúng sẽ chạy ra "trạm lưu trữ chung" (Redis) để cất và lấy giỏ hàng của người dùng.

  • Nếu Server A sập, Load Balancer đẩy người dùng sang Server B. Server B chỉ cần chạy ra trạm chung, lấy lại giỏ hàng và tiếp tục phục vụ người dùng trơn tru như chưa hề có cuộc chia ly.

Phần 6: Auto-scaling (Tự động mở rộng)

Đến đây, hệ thống của chúng ta đã phân tải tốt, bảo mật cao và chịu lỗi giỏi. Nhưng hãy tưởng tượng đến ngày Black Friday, lượng truy cập không chỉ gấp đôi mà gấp 100 lần ngày thường. Cả Server A, B và C đều hoạt động 100% công suất và sắp quá tải. Chúng ta cần "gọi thêm viện binh" (mở rộng thêm Server D, E, F...).

Theo bạn, Load Balancer có thể đóng vai trò gì trong quá trình hệ thống tự động sinh ra các máy chủ mới (Auto-scaling) này? Làm sao hệ thống biết lúc nào cần gọi viện binh và lúc nào cần giải tán bớt để tiết kiệm tiền?

Trong một hệ thống hiện đại (thường triển khai trên Cloud như AWS, Google Cloud), Load Balancer (LB) không tự mình sinh ra máy chủ mới. Nó hoạt động như một "người đo lường" và làm việc chặt chẽ với một bộ phận khác gọi là Auto Scaling Group (Nhóm tự động mở rộng).

Quá trình này diễn ra theo một chu trình khép kín với 3 bước cốt lõi:

1. Thu thập "tín hiệu" (Metrics)

Để biết lúc nào cần hành động, hệ thống phải liên tục đo lường. Có 2 loại tín hiệu chính:

  • Tín hiệu từ Server: Nhóm Auto Scaling tự theo dõi mức sử dụng CPU hoặc RAM của các Server (Ví dụ: CPU trung bình vượt quá 70%).

  • Tín hiệu từ Load Balancer: LB báo cáo về số lượng request đang đổ về. (Ví dụ: "Mỗi máy chủ đang phải gánh 1000 requests/giây, quá ngưỡng an toàn").

2. Gọi viện binh (Scale Out)

Khi tín hiệu chạm ngưỡng báo động, kịch bản sau sẽ diễn ra:

  1. Nhóm Auto Scaling tự động tạo ra một (hoặc nhiều) Server mới.

  2. Server mới khởi động xong, chạy ứng dụng lên.

  3. Nhóm Auto Scaling đem IP của Server mới này "đăng ký" với Load Balancer.

  4. Quan trọng: Load Balancer chưa cho Server mới làm việc ngay! Nó sẽ dùng cơ chế Health Check để kiểm tra vài lần. Khi nào chắc chắn Server mới đã thực sự sẵn sàng (trả về 200 OK), nó mới bắt đầu chia sẻ lượng truy cập sang.

Giải tán bớt (Scale In) và Cơ chế "Rút lui an toàn"

Khi đợt sóng truy cập qua đi, CPU giảm xuống dưới 30%, hệ thống cần tắt bớt máy chủ để tiết kiệm tiền. Nhưng tắt máy chủ không đơn giản là "rút phích cắm", vì có thể người dùng đang dở dang quá trình thanh toán trên máy chủ đó.

Load Balancer sử dụng một cơ chế cực kỳ tinh tế gọi là Connection Draining (Rút cạn kết nối) hay Deregistration Delay:

  • Nó đánh dấu Server sắp bị tắt là "Đang rút lui".
  • LB ngừng gửi request mới vào Server này.
  • LB đợi các request cũ hoàn thành nốt (thường cho phép tối đa 30-300 giây).
  • Sau khi Server rảnh rang hoàn toàn, LB mới chính thức gạch tên, và hệ thống sẽ an toàn xóa sổ Server đó.

Phần 7: Global Routing (GSLB)

Đến đây, chúng ta đã giải quyết được trọn vẹn bài toán chịu tải khổng lồ tại một cụm Data Center (Trung tâm dữ liệu).

Tuy nhiên, hãy nghĩ đến một rào cản vật lý: Tốc độ ánh sáng. Nếu máy chủ của bạn đặt tại Mỹ, thì dù bạn có 1000 cái Server xịn và Load Balancer hoàn hảo, một khách hàng ở Việt Nam truy cập vào vẫn sẽ cảm thấy độ trễ (ping cao) do khoảng cách địa lý nửa vòng trái đất.

Theo bạn, để giải bài toán "khoảng cách" này ở quy mô toàn cầu, người ta sử dụng cơ chế cân bằng tải đặc biệt nào để hướng người dùng Việt Nam về Data Center ở Châu Á, còn người dùng Mỹ thì về Data Center ở Bắc Mỹ?

Để giải quyết rào cản vật lý về "tốc độ ánh sáng" và khoảng cách địa lý, chúng ta phải đưa Load Balancer lên một tầm cao mới. Lúc này, chiếc Load Balancer thông thường nằm tại một Data Center là không đủ nữa. Chúng ta cần sử dụng Global Server Load Balancing (GSLB) - Cân bằng tải toàn cầu.

Công nghệ cốt lõi đứng sau GSLB chính là DNS (Hệ thống phân giải tên miền).

Bạn có thể hình dung DNS giống như một "Tổng đài danh bạ điện thoại" của Internet. Khi bạn gõ website.com, trình duyệt sẽ gọi cho DNS hỏi: "Số IP của trang web này là gì?". Thay vì trả về một số IP cố định cho tất cả mọi người, hệ thống DNS thông minh (như Amazon Route 53 hoặc Cloudflare) sẽ làm các bước sau:

  1. Xác định vị trí (Geolocation): Nó nhìn vào địa chỉ IP của người hỏi để biết người đó đang ở đâu (Ví dụ: IP này ở Hà Nội, Việt Nam).

  2. Đo lường khoảng cách/Độ trễ: Nó biết hệ thống của bạn có 2 cụm Data Center: một ở Mỹ và một ở Singapore (Châu Á).

  3. Trả về kết quả tối ưu (Geo-Routing): Nó sẽ trả về địa chỉ IP của Data Center Singapore cho khách hàng Việt Nam (độ trễ chỉ khoảng 30ms). Ngược lại, nếu một người ở New York truy cập, DNS sẽ trả về IP của Data Center Mỹ (độ trễ 10ms).

Nhờ "người tổng đài" thông minh này, không ai phải bay nửa vòng trái đất để tải một trang web cả.

Bên cạnh DNS Routing, các ông lớn công nghệ còn dùng một kỹ thuật phần cứng mạng gọi là Anycast (một dải IP duy nhất được phát sóng trên toàn cầu, router mạng sẽ tự động hút gói tin về trạm vật lý gần nhất).

🎓 Tổng kết Hành trình Load Balancer

Tuyệt vời! Chúng ta đã đi qua trọn vẹn 7 trạm dừng chân quan trọng nhất của Load Balancer, đi từ cốt lõi bên trong ra đến quy mô toàn cầu:

  1. Thuật toán (Algorithms): Round Robin, Least Connections, IP Hash.

  2. Phân loại OSI: Layer 4 (Nhanh, dựa trên IP/Port) vs Layer 7 (Thông minh, dựa trên HTTP/URL).

  3. Health Check: Cơ chế bắt mạch tự động & Chống điểm lỗi duy nhất (SPOF).

  4. Bảo mật SSL: SSL Termination (Giảm tải cho server) vs SSL Passthrough (Mã hóa toàn trình).

  5. Sticky Session: Dùng Cookie để giữ giỏ hàng & Lưu trữ tập trung với Redis.

  6. Auto-scaling: Phối hợp nhịp nhàng để gọi viện binh và rút lui (Connection Draining).

  7. Global Routing (GSLB): Dùng DNS để giải bài toán địa lý toàn cầu.

Kiến thức của bạn về Load Balancer lúc này đã ở mức của một Kỹ sư hệ thống (System Design Engineer) rồi đấy!

Để thử thách khả năng tổng hợp của bạn, tôi có một bài toán thực tế cuối cùng: Nếu bạn được giao nhiệm vụ thiết kế hệ thống Load Balancer cho một ứng dụng gọi xe (như Grab hoặc Uber) – nơi mà người dùng liên tục di chuyển, dữ liệu tọa độ cần cập nhật theo thời gian thực (real-time) nhưng thỉnh thoảng mạng 4G/5G của họ lại bị rớt.

Theo bạn, trong 7 công cụ chúng ta vừa học, những tính năng nào sẽ đóng vai trò "sống còn" nhất cho ứng dụng này? Câu trả lời sẽ có ở dưỡi comment nhé


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.