Avatar
1
Nguyen Van Huy Beginner
Nguyen Van Huy Beginner
Thắc mắc về building infra ứng dụng chat
Anh Dũng ơi,

Em đang nghiên cứu về system design ứng dụng chat có khả năng scale nhiều WebSocket server, và em đang nghĩ cách là dùng Redis Pub/Sub để broadcast message giữa các server. Tuy nhiên, em đang không rõ nếu Redis (kể cả trong trường hợp sử dụng Redis Cluster) bị downtime thì các WebSocket server sẽ nhận message như thế nào?

Liệu giải pháp hợp lý trong trường hợp này có nên là truy vấn lại message từ database không ạ?

Anh có thể giải thích giúp em hướng xử lý phù hợp hoặc best practice cho tình huống này không ạ?

  • Answer
Remain: 5
2 Answers
Avatar
tvd12 Beginner
tvd12 Beginner
The Best Answer
Dùng redis cũng là một ý tưởng tốt em ạ, nhưng dùng redis đúng như em nói khi cluster bị down thì tin nhắn từ server A có thể không broadcast đến B, C được dẫn đến những client kết nối đến B, C không nhận được tin nhắn.

Vậy nên giải pháp đưa ra là tin nhắn vẫn phải được lưu ở trong cơ sở dữ liệu nữa. Khi client kết nối với bất kỳ server nào thì nó sẽ đồng bộ tin nhắn (tính từ tin nhắn cuối cùng mà nó nhận được), server cũng sẽ gửi các tin nhắn cho client tính từ tin nhắn lần cuối nó gửi cho các client, ví dụ:

  1. Server A: Nhận được tin nhắn thứ 100, nó cần broadcast đến B để gửi cho client X, nhưng cluster down, vậy B sẽ vẫn còn trạng thái là last message id = 99.
  2. Trường hợp cluster không kịp sống lại và client disconnect sau đó kết nối vào A thay vì B thì client sẽ đồng bộ lại toàn bộ tin nhắn tính từ 99.
  3. Trường hợp cluster sống lại thì B sẽ lại tiếp tục lấy tin nhắn từ 99 và gửi cho các client bao gồm cà X, client vẫn giữ kết nối đến B nên tiếp tục nhận được tin nhắn.

Nhìn chung vẫn phải kết hợp nhiều thứ chứ không chỉ Redis hay DB là đủ em ạ, DB cung cấp giải pháp lưu trữ bền bỉ, còn redis cung cấp giải pháp thông báo cho các websocket server biết có tin nhắn mới để mà vào DB lấy ra rồi gửi đi và cập nhật trạng thái.

  • 1
  • Reply
làm sao để biết redis down mà lấy message từ db a nhỉ, có thể coi connect lỗi (có thể là kết nối mạng) là down không ạ  –  Nguyen Van Huy 1745208257000
Avatar
tvd12 Beginner
tvd12 Beginner
Làm sao để biết Redis down? Thực tế thư viện nào cũng cung cấp cơ chế ping pong để biết được trạng thái của Redis là gì để kết nối lại hoặc bắn ra lỗi để em có thể em gửi về hệ thống monitoring.

Trên thực tế thì việc lấy message ở máy chủ B có thể là:

  1. Đợi có message bắn sang từ A.
  2. Chạy 1 vòng loop liên tục để kiểm tra xem có message mới không (ví dụ 100ms 1 lần).

Kết hợp cả 2 cái này thì dù Redis có down hay không thì Websocket Server vẫn hoạt động bình thường được.

Như em có thể thấy không nhất thiết phải có Redis đâu, tất nhiên có redis thì nhiều khi tin nhắn được bắn ngay mà đỡ phải bị deplay 100ms

  • 1
  • Reply
Vậy là khi ping redis mà xác nhận nó down thì mình sẽ chạy cái vòng loop để lấy message từ db cho đến khi redis phục hồi phải không ạ  –  Nguyen Van Huy 1745217530000
Có thể như vậy em ạ  –  tvd12 1745234992000