Khó nhưng vẫn làm được

Thường ngày chúng ta vẫn thường quen làm việc với HTTP và việc scale ngang với HTTP cũng không quá khó khăn, vì HTTP là giao thức stateless, nghĩa là client với server sẽ cắt đứt liên hệ với nhau sau khi thực hiện xong 1 request. Vậy có thể đơn thuần là chúng ta tăng số lượng server theo mô hình dưới đây là có thể phần nào đó giải quyết được vấn đề:

Nhưng với socket thì lại khác, nó là giao thức statefull, server và client sẽ giữ kết nối với nhau, mà vấn đề một card mạng chỉ có tối đa 65535 port chính vì vậy nó mới nảy sinh nhiều vấn đề, tuy vậy vẫn có thể giải quyết được.

Trong bài viết này chúng ta sẽ sử dụng ezyfox server để làm socket server, chúng ta sẽ chỉ nói về TCP và Websocket thôi nhé.

Giải pháp truyền thống

Sử dụng mô hình truyền thống thì chúng ta sẽ có:

  1. Load balancer (LB): để cân bằng tải, đảm bảo HA
  2. Các socket server ở phía sau: xử lý yêu cầu của người dùng

Vấn đề

Chúng ta sẽ có rất nhiều client kết nối đến load balancer (nginx), có thể hàm trăm nghìn, thậm chí hàng triệu, và bản thân 1 socket server như ezyfox server cũng có thể chịu được hàng trăm nghìn đến hàng triệu CCU với cấu hình đủ mạnh, tuy nhiên với 1 card mạng và tối đa 65 nghìn cổng thì cũng chỉ có thể đáp ứng được 65 nghìn CCU mà thôi, như vậy thì dù socket server có mạh đến cỡ nào đi chăng nữa thì hệ thống cũng chỉ đáp ứng được 65 nghìn user mà thôi. Vì sao vậy? Vì khi 1 client kết nối đến LB, bởi vì cần giữ kết nối nên LB phải mở 1 cổng để kết nối đến socket server, mỗi một cổng sẽ đại diện cho 1 client.

Giải pháp

Để giải quyết vấn đề này thì chúng ta có thể cắm thêm nhiều card mạng, hoặc mua giải pháp elatic sever với elastic network interfaces để cấp được nhiều IP cho load balancer, tuy nhiên, trong thời điểm hiện tại thì số lượng IPv4 có hạn nên việc cấp IP là không đơn giản, có lẽ chúng ta sẽ chỉ nên cấp tối đa 50 IP và giải pháp này sẽ phù hợp với các hệ thống phục vụ dưới 3 triệu CCU mà thôi.

Ưu điểm

Cơ bản thì giải pháp này khá đơn giản và quen thuộc với những gì chúng ta đã làm trong suốt nhiều năm, chúng ta có thể tái sử dụng các hạ tầng đã có sẵn mà không cần thêm các dịch vụ hỗ trợ đi kèm

Nhược điểm

Khá tốn card mạng, IP và chỉ đáp ứng được một số lượng CCU nhất định, hơn nữa việc chỉ có 1 server LB cũng là điểm nghẽn của toàn bộ hệ thống.

Giải pháp tách rời

Vấn đề của giải pháp truyền thống là chúng ta bị phụ thuộc vào khả năng của LB, vậy ý tưởng bây giờ đó là bỏ LB đi, không cần nó nữa để tận dụng được hết sức mạnh của socket server.

Theo mô hình này thì chúng ta sẽ có các thành phần:

  1. Dịch vụ quản lý và cung cấp server url để cho client kết nối đến
  2. Các socket server để client trực tiếp kết nối đến
  3. Hệ thống mesage broker hỗ trợ cho socket server trao đổi dữ liệu cho nhau và đồng bộ dữ liệu xuống cơ sở dữ liệu
  4. Hệ thống API nội bộ để socket server gọi xác thực user hay lấy dữ liệu, trên thực tế hệ thống này có thể không cần thiết, socket server có thể gọi trực tiếp đến cơ sở dữ liệu
  5. Hệ thống API cung cấp cho client cho các task vụ nặng, lấy nhiều data, thực tế hệ thống này cũng có thể bỏ đi và socket server có thể gọi trực tiếp đến cơ sở dữ liệu

Ưu điểm

Giải pháp này giúp giảm thiểu số lượng IP cần cung cấp, ví dụ mỗi một socket server có thể phục vụ 1 triệu CCU thì chỉ với 3 IP là chúng ta đã có thể phục vụ được 3 triệu CCU rồi

Nhược điểm

Tương đối phức tạp để cài đặt, chúng ta phải cài đặt thêm dịch vụ cung cấp server url cho client, từ đó mà tăng thêm chi phí vận hành cho doanh nghiệp

Khi nào cần scale

Nói đến scale rồi thì cũng phải nói đến khi nào cần phải scale chứ nhỉ. Rất nhiều bạn hỏi mình rằng ezyfox server có đáp ứng được 10 triệu CCU không, và câu trả lời hoàn toàn có thể. Nhưng để đạt được số CCU thế không phải là câu chuyện đùa.

Vậy có cách nào để xác định khi nào cần scale không? Đó là khi bạn theo dõi và thấy lượng CCU đạt đến ngưỡng của hệ thống, và bạn cần có giải pháp nâng cấp ngay. Tuy nhiên nếu muốn xác định số lượng server cần scale ngay từ ban đầu bạn có thể dùng lý thuyết 80/20. Hệ thống của bạn có N user, trong một tháng có X = 20%N user active thì 1 ngày có Y = 20%X user active và tại 1 thời điểm sẽ có Z = 20%Y CCU, vậy khi nào hệ thống của bạn có 1 tỉ 250 triệu user thì bạn mới cần đến 10 server cho 10 triệu CCU. Lý thuyết này có vẻ không đúng lắm nhỉ, vậy bạn hãy tự kiểm chứng xem sao nhé.

Tổng kết

Về cơ bản thì việc scale socket server cũng không khác gì so với scale HTTP server, cùng là những cách đó, tuy nhiên HTTP thì đơn giản hơn vì nó là giao thức ngắt kết nối nên rất khó để làm hết port của LB cũng vì thế mà nó không đòi hỏi nhiều IP.

Nhìn chung để đến lúc chúng ta phải tính đến phương án scale up hệ thống socket server thì chắc chúng ta cũng phải là một doanh nghiệp tương đối lớn với hàng trăm nghìn user rồi, nên đừng quá lăn tăn ở giai đoạn đầu phát triển dự án mọi người nhé.