Thiết kế Messaging Service WhatsApp – P1
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.
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](https://mllo3znnpf9h.i.optimole.com/BQmFdjA-wVCOVYTN/w:1024/h:590/q:auto/https://kieblog.vn/wp-content/uploads/2021/03/Capture-1.png)
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](https://mllo3znnpf9h.i.optimole.com/BQmFdjA-6MDyam4N/w:auto/h:auto/q:auto/https://kieblog.vn/wp-content/uploads/2021/03/messaging-service-design-system-2.png)
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](https://mllo3znnpf9h.i.optimole.com/BQmFdjA-mJN0hwzD/w:auto/h:auto/q:auto/https://kieblog.vn/wp-content/uploads/2021/03/messaging-service-design-system.png)
- Đầ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ế.
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:
- Bí kíp để host apps hoàn toàn miễn phí
- Messaging App sẽ định hình lại E-commerce
- Service Provider là gì? Tìm hiểu Service Provider trong Laravel
Xem thêm Việc làm Developer hấp dẫn trên TopDev
- C Cách tích hợp ChatGPT vào Google Search siêu dễ
- V VoiceGPT là gì? Giới thiệu tính năng và cách cài đặt sử dụng Voice GPT
- G GPT-4o Mini – Thông minh hơn và tiết kiệm hơn?
- C ChatGPT-4o là gì? Điểm mới của ChatGPT-4o vs ChatGPT-4
- C Chat GPT 4.0 là gì? Có gì vượt trội so với Chat GPT phiên bản cũ?
- C Cách tự học code web, tìm kiếm công việc dễ dàng và hạnh phúc mỗi ngày
- G Giới thiệu 15 website học và luyện hack hợp pháp
- T Tầm quan trọng của các chương trình đào tạo sau đại học trong kỷ nguyên 4.0
- i iOS 17.5 Beta 1 vừa được phát hành, những thay đổi nào đáng chú ý?
- i iOS 18 khi nào ra mắt? iOS 18 sẽ không hỗ trợ máy nào?