Thiết kế Messaging Service WhatsApp – P1

576

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Tiếp sau chuỗi bài viết về thiết kế hệ thống TinyURL, Kieblog tiếp tục giới thiệu chuỗi bài viết về System Design, hôm nay là Messaging Service.

  Discord đã lưu trữ hàng tỉ messages mỗi ngày như thế nào
  Kafka là gì? Ứng dụng Kafka cho hệ thống message

Chat là hệ thống lớn, bao gồm nhiều thành phần và nhiều vấn đề cần giải quyết. Đại thể có thể nói tới: gửi file, các tệp định dạng khác nhau, group chat, thả reaction, …

Chính vì vậy, tóm gọn trong nội dung bài viết, ta chỉ xem xét qua thiết kế hệ thống Chat ở mức basic nhất có thể, qua đó hiểu thêm về Load Balancers và Scalable Web Application.

Bắt đầu ngay thôi!

1. Yêu cầu hệ thống

Messaging Service khi thiết kế yêu cầu phải có những tính năng tối thiểu như sau:

  • Send and receive text messages between two devices – Gửi và nhận tin nhắn giữa hai thiết bị
  • One-on-one conversations with different users – Giao tiếp 1 vs 1 với các user khác nhau trong hệ thống
  • User can see the time of each message – User có thể thấy được thời gian khi gửi từng tin nhắn

Do bài viết có giới hạn nên mình chỉ đề cập tới thiết kế một hệ thống Chat đơn giản:

  • Messages are one-on-one only, i.e, no group messages – Tin nhắn gửi 1-1, không có chat theo nhóm
  • Our server will not store the messages after they’re delivered – Server sẽ không lưu tin nhắn sau khi đã gửi
  • Our messages will be text-only – Nội dung tin nhắn tạm thời chỉ là text.

2. User case Messaging Service

Về user case cơ bản của hệ thống được thiết kế gồm có:

  • Send a message to a person – Gửi tin nhắn tới ai đó
  • If you receive a message and you are online, immediately deliver it. – Nếu nhận được tin nhắn và đang online, tin nhắn tới ngay lập tức.
  • If you receive a message and you are offline, wait till you come online – Nếu nhận được tin nhắn và đang offline, chờ tới khi online trở lại.
  • Get a notification and receive a message – Thông báo khi nhận được tin nhắn mới
Messaging Service

Về phía user, nội dung lưu trữ cũng không cần quá nhiều.

Java

User:

- id

- username

- password

- list<unread_messages>

Java

Message Properties:

- message text

- timestamp

- sender's Id

Rồi, cơ bản về User, System Requirement đơn giản chỉ cần có vậy. Bắt đầu đi sâu hơn vào phần thiết kế tính năng quan trọng nhất – Gửi tin nhắn.

3. Xử lí gửi và nhận tin nhắn

Không lòng vòng lèo vèo, về cơ bản, có hai cách để xử lí gửi tin nhắn là Push và Pull. Ta sẽ tìm hiểu chi tiết từng loại, ưu nhược điểm khi sử dụng trong Messaging Service System.

Đầu tiên là PULL

This is a less sophisticated way to “send” notifications. The device can periodically ask the server if there are any new messages. Say every 2 minutes, the device sends a REST API request to check if there are new messages, and the server responds with yes or no.

PULL là cách đơn giản để gửi notifications. Thiết bị sẽ gửi request tới server định kì trong một khoảng thời gian nhất định về tin nhắn mới. Cứ mỗi 2 phút, sẽ gửi REST API kiểm tra xem có tin nhắn mới hay không, server sẽ phản hồi với có hoặc không.

Cách này rõ ràng tồn tại hai nhược điểm lớn:

  • Độ trễ cao, nếu thời gian định kì lớn thì tin nhắn bị delay quá lâu, không thể chấp nhận tới tận 2 phút.
  • Tuy nhiên, nếu thời gian quá ngắn, request server phải nhận là cực kì lớn. Số lượng người dùng tới vài triệu -> toang.

Một phương thức khác cũng sử dụng PULL là Long Polling. Khi gửi request, server sẽ hold cho tới khi có tin nhắn mới và trả về response.

Thứ hai là PUSH

Thay vì chỉ giao tiếp một chiều với client ở phía chủ động gửi request. Tại sao không giữ connection liên tục giữa client và server sau khi đã mở

Once the client initiates the connection though, it can be kept alive and there can be bi-directional communication.

Tuy nhiên, một khi client khởi tạo kết nối, nó có thể được giữ nguyên và có thể giao tiếp hai chiều. Đó là cơ sở để đẩy dữ liệu đến các device.

3.1 Websocket

Websocket là lựa chọn tốt, đáng để cân nhắc

These are a good choice. WebSockets give you a single bi-directional connection over TCP. Once the connection is established, the client and server can freely exchange information.

Websocket cung cấp kết nối hai chiều (bi-driectional) duy nhất thông 1qua TCP. Một khi kết nối đã được khởi tạo, client và server có thể thoải mái để trao đổi thông tin

3.2 Push Notifications

Với push notification thì hện tại đã có nhiều sự lựa chọn tới từ Google hoặc Apple, mặc dù đôi khi chúng thường chậm hơn Websocket. Tuy nhiên các vấn đề vặt vãnh xung quanh đó thì lại hỗ trợ tốt hơn

Apple thì có Apple Push Notification Service (APNS), hỗ trợ tốt cho các thiết bị iOS. Google thì hỗ trợ với Firebase Cloud Messaging (FCM).

Messaging Service

Với tam giác ba điểm kết nối, Notification cho device iOS hay Android trở nên đơn giản hơn bao giờ hết. Mỗi khi server nhận được tin nhắn mới, nó sẽ gửi request Push Notification tới APNS hoặc GCM. Tuy nhiên, giới hạn cho notification với APNS là nội dung maximum có thể gửi tối đa dừng ở mức 2KB

3.3 Còn với XMPP?

XMPP cũng là một loại protocol phổ biến để messaging communications. XMPP is a protocol (giống như HTTP). Cũng có thể kết hợp XMPP với Websockets và Long Polling

4. Bắt tay vào thiết kế

Thiết kế đơng giản cho Messaging Service như sau. Lưu ý phần Caching và CDN có thể xử lí sau

Messaging Service
  • Đầu tiên, phía App Server sẽ là stateless, không quan tâm tới trạng thái của client. Cũng không lưu trữ gì ở đây (not store anything). App Server sẽ chỉ nhận request và lưu vào distributed In-Memory Cache và NoSQL
  • Khi App Server nhận được request từ notification rằng có message mới, App Servers sẽ đọc từ cache, nếu cache không có thì thực hiện query
  • Phần Load Balancer và Distributed Database tất nhiên là phần không thể thiếu cho các hệ thống muốn large scale

Trên đây là thiết kế tổng quan cho hệ thống, sẽ có phần 2 phân tích kĩ càng hơn về các feature, trả lời các câu hỏi về kĩ thuật cũng như các vấn đề có thể phải giải quyết trong thực tế.

Anh em đón đọc phần 2 ở đây. Thiết kế Messaging Service WhatsApp Part 2

5. Tham khảo

Thank for reading – Have a great week – Happy coding!

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev