CƠ SỞ LÝ THUYẾT
Framework
ReactJS là một thư viện JavaScript được sử dụng rộng rãi để xây dựng giao diện người dùng, đặc biệt là trong các ứng dụng có nội dung động Được phát triển và duy trì bởi Facebook, ReactJS tuân theo kiến trúc dựa trên thành phần, giúp tăng khả năng tái sử dụng và dễ bảo trì Virtual DOM của nó cập nhật hiệu quả chỉ những phần thay đổi trong DOM thực tế, giúp cải thiện hiệu suất ReactJS cũng hỗ trợ khái niệm luồng dữ liệu một chiều, giúp quản lý trạng thái và điều khiển dữ liệu trong ứng dụng một cách dễ dàng.
FastAPI là một web framework hiện đại, nhanh chóng (hiệu suất cao) được sử dụng để xây dựng API với Python 3.7+ dựa trên gợi ý kiểu dữ liệu tiêu chuẩn của Python Nó được thiết kế để sử dụng dễ dàng, đồng thời cũng mạnh mẽ và chắc chắn FastAPI tận dụng sức mạnh của lập trình không đồng bộ, làm cho nó phù hợp cho việc xử lý một lượng lớn các yêu cầu đồng thời Với khả năng tự động tạo OpenAPI và JSON Schema, FastAPI đơn giản hóa việc thiết lập documentation và kiểm tra API.
Gorilla Websocket là một thư viện WebSocket cho ngôn ngữ lập trình Golang,được sử dụng để xây dựng các ứng dụng thời gian thực và truyền tải dữ liệu một cách hiệu quả Với Gorilla Websocket, việc thiết lập và duy trì kết nối WebSocket trở nên đơn giản, giúp ứng dụng tương tác và giao tiếp trực tiếp với server.
Database
PostgreSQL là hệ quản trị cơ sở dữ liệu mạnh mẽ và có khả năng mở rộng Được ưa chuộng trong các dự án có yêu cầu về tính nhất quán, bảo mật, và độ tin cậy cao, PostgreSQL hỗ trợ nhiều loại dữ liệu và cung cấp các tính năng như giao dịch, phân quyền, và truy vấn phức tạp, làm cho nó trở thành lựa chọn lý tưởng cho việc lưu trữ dữ liệu trong các ứng dụng phức tạp.
Redis là hệ thống cơ sở dữ liệu lưu trữ key-value có hiệu suất cao, được sử dụng chủ yếu để lưu trữ dữ liệu tạm thời và cache Với khả năng xử lý dữ liệu nhanh chóng và hỗ trợ nhiều kiểu dữ liệu, Redis là một công cụ linh hoạt và mạnh mẽ cho việc quản lý và truy cập dữ liệu trong ứng dụng.
ScyllaDB là một hệ cơ sở dữ liệu NoSQL, sử dụng kiến trúc Apache Cassandra để cung cấp hiệu suất cao và khả năng mở rộng tốt Với thiết kế phân tán và khả năng đồng bộ, ScyllaDB thích hợp cho các ứng dụng đòi hỏi xử lý dữ liệu lớn và đồng thời đảm bảo sự đồng nhất và tin cậy.
Công cụ hỗ trợ
RabbitMQ là một dịch vụ message queue giúp các thành phần trong hệ thống giao tiếp và truyền thông tin một cách linh hoạt Với RabbitMQ, việc xử lý hàng đợi và truyền tải thông điệp giữa các ứng dụng trở nên dễ dàng, tăng tính ổn định và mở rộng của hệ thống.
Prometheus là một hệ thống giám sát và cảnh báo mã nguồn mở, được thiết kế để theo dõi các thành phần trong hệ thống Prometheus tự động thu thập thông tin và cung cấp giao diện để theo dõi hiệu suất, giúp quản trị viên hệ thống giữ cho ứng dụng luôn hoạt động mượt mà.
Grafana k6 là một công cụ giám sát hiệu suất cho phép kiểm tra và đánh giá độ ổn định của hệ thống Kết hợp giữa Grafana và k6, nó cung cấp thông tin chi tiết về hiệu suất và khả năng chịu tải của ứng dụng, giúp nhận diện và khắc phục vấn đề nhanh chóng.
Vận hành & quản lý
Ubuntu Server là một hệ điều hành Linux phổ biến được sử dụng cho việc triển khai ứng dụng và quản lý máy chủ Với sự ổn định và hỗ trợ cộng đồng lớn, Ubuntu Server là một lựa chọn phổ biến cho việc vận hành hệ thống và triển khai ứng dụng.
Docker là một nền tảng ảo hóa dựa trên container, giúp đóng gói ứng dụng và tất cả các phụ thuộc của chúng vào một container duy nhất Điều này tạo ra môi trường đồng nhất và di động, giúp triển khai ứng dụng dễ dàng và hiệu quả.
Jenkins là một công cụ tự động hóa CI/CD (continuous integration/continuous delivery) giúp quản lý và triển khai mã nguồn một cách liên tục Với Jenkins, quy trình phát triển và triển khai ứng dụng trở nên tự động và có thể lặp đi lặp lại, giúp
Grafana là một công cụ giám sát và trực quan hóa dữ liệu, thường được sử dụng để hiển thị và phân tích thông tin từ các nguồn khác nhau Grafana cung cấp giao diện đồ họa mạnh mẽ và linh hoạt, giúp quản trị viên hệ thống theo dõi hiệu suất và đưa ra quyết định thông minh.
NGINX là một máy chủ web và reverse proxy rất phổ biến, được sử dụng để xử lý và chuyển hướng các yêu cầu HTTP Với khả năng xử lý tải cao và cấu hình linh hoạt, NGINX là một phần quan trọng trong việc triển khai ứng dụng web và cung cấp các dịch vụ proxy đáng tin cậy.
PHÂN TÍCH THIẾT KẾ HỆ THỐNG
Phân tích thực tế
Ngày nay, thị trường giao tiếp tin nhắn trực tuyến đang cực kỳ đa dạng với nhiều sản phẩm có quy mô lớn đi kèm với số lượng người dùng đông đảo Có thể kể đến nhiều nền tảng phổ biến như WhatsApp, Facebook Messenger, WeChat, Telegram, Discord, Zalo (tại Việt Nam), …, các ứng dụng này thu hút hàng tỷ người dùng trên toàn thế giới, tạo ra sự cạnh tranh khốc liệt trong việc cung cấp trải nghiệm người dùng tốt nhất và đáp ứng nhu cầu đa dạng của họ
Hình 2.1 Biểu đồ số lượng người dùng khả dụng trong tháng đối với các ứng dụng
3.1.2 Hiện trạng của các nền tảng giao tiếp tin nhắn phổ biến
Các nền tảng lớn hiện nay đã và đang tối ưu hệ thống của họ nhằm xử lý hàng tỷ tin nhắn mỗi ngày từ người dùng theo thời gian thực, cùng với đó vẫn liên tục phát triển các tính năng mới nhằm thu hút người dùng sử dụng.
Hình 2.2 Biểu đồ số lượng tin nhắn được ứng dụng WhatsApp xử lý hằng ngày, xét theo từng quý của năm 2023, Statista [2]
Như ở hình trên, ứng dụng WhatsApp là một trong những ứng dụng tin nhắn có số lượng người dùng lớn nhất trong các nền tảng social media hiện tại, và cũng vì thế số lượng dữ liệu phải xử lý đằng sau hệ thống cũng là một con số khổng lồ, kể cả khi xét trên vài năm về trước.
Tuy nhiên, việc sử dụng các nền tảng lớn kể trên hiện nay đều có những điểm mạnh và điểm yếu rõ ràng mà ta cần phân tích trước khi áp dụng.
3.1.3 Ưu điểm của các nền tảng hiện tại
3.1.3.1 Khả năng tiếp cận dễ dàng
Trong thực tế, các nền tảng như WhatsApp, Facebook Messenger và Telegram đều nổi bật với khả năng tiếp cận dễ dàng Các ứng dụng này đều có sẵn trên nhiều nền tảng, bao gồm cả điện thoại di động và máy tính, giúp người dùng kết nối mọi lúc, mọi nơi Ngoài ra, việc đăng nhập thông qua các tài khoản mạng xã hội cũng giúp việc tiếp cận trở nên thuận tiện và nhanh chóng.
3.1.3.2 Đa dạng chức năng & công cụ hỗ trợ
Các nền tảng giao tiếp tin nhắn hiện tại đều hỗ trợ một loạt các chức năng và công cụ giúp người dùng trải nghiệm đa dạng Từ gửi tin nhắn văn bản, hình ảnh, gắn thẻ người dùng đến cuộc gọi video và tạo nhóm, các ứng dụng này đáp ứng đầy đủ nhu cầu giao tiếp của người dùng hiện đại
Và cùng với đó các chức năng mới vẫn đang được phát triển liên tục, ví dụ như tính năng nhắn tin ẩn và trò chơi hội nhóm tích hợp bên trong phòng chat.
3.1.3.3 Hỗ trợ lưu lượng người dùng lớn & độ trễ thấp
Với số lượng người dùng khổng lồ, các nền tảng như WhatsApp, Facebook Messenger và WeChat đã chứng minh khả năng hỗ trợ lưu lượng người dùng khổng lồ mà vẫn giữ được độ trễ tối thiểu trong đường truyền của tin nhắn bằng sự đầu tư mạnh mẽ vào cơ sở hạ tầng và thiết kế của hệ thống Điều này đặc biệt quan trọng trong việc duy trì trải nghiệm người dùng mượt mà, hiệu quả và không gây khó chịu, từ đó giữ người dùng sử dụng nền tảng.
3.1.4 Nhược điểm của các nền tảng hiện tại
3.1.4.1 Bảo mật và quyền riêng tư
Mặc dù các nền tảng giao tiếp tin nhắn đã đưa ra nhiều biện pháp bảo mật, nhưng vẫn tồn tại những điểm yếu đối với quyền riêng tư và bảo mật dữ liệu người dùng Đặc biệt, những vấn đề như lỗ hổng trong chính sách chia sẻ dữ liệu có thể tạo nên nguy cơ đối với sự riêng tư của dữ liệu người dùng.
3.1.4.2 Sự minh bạch về dữ liệu người dùng Đi kèm với các chính sách ngầm phức tạp, mức độ minh bạch về việc thu thập và sử dụng dữ liệu người dùng cũng là một vấn đề gặp nhiều tranh cãi, nhất là khi các tổ chức & công ty lớn như Meta (sở hữu WhatsApp, Messenger) và Tencent (sở hữu WeChat) thường không có lịch sử tốt về việc sử dụng dữ liệu người dùng
3.1.4.3 Khả năng tự vận hành & quản lý
Các ứng dụng kể trên không công khai kiến trúc, và việc sử dụng ứng dụng phải phụ thuộc vào hạ tầng của công ty sở hữu, điều đó gây khó khăn nếu quản lý toàn bộ dữ liệu nhằm tối đa khả năng bảo mật (ví dụ như dữ liệu nội bộ doanh nghiệp)
3.1.5.1 Các vấn đề đồ án nhắm tới
Phương hướng của đồ án sẽ nhắm đến việc học hỏi, áp dụng các điểm mạnh về hiệu năng cũng như độ mở rộng của các hệ thống lớn có sẵn, cùng với đấy là thiết kế các cấu trúc, tính năng riêng để giải quyết các vấn đề bất cập và phục vụ cho các nhóm người dùng cần những tính năng kể trên Ngoài ra, đồ án cũng hướng tới việc cải thiện khả năng tự vận hành và quản lý từ phía người dùng.
3.1.5.2 Các nền tảng tương tự
Chúng ta có thể tham khảo các nền tảng tin nhắn mã nguồn mở khá phổ biến như:
Signal : hệ thống nhắn tin mã nguồn mở miễn phí cho iOS, Android và desktop, tập trung vào khả năng bảo mật cực kỳ mạnh và tính năng đầy đủ cho đa số nhu cầu người dùng.
Element: hệ thống nhắn tin mã nguồn mở miễn phí cung cấp khả năng mã hoá end-to-end, cùng với việc tích hợp với các dịch vụ khác như Discord, Slack và cung cấp khả năng tự vận hành.
Let’s Chat: ứng dụng nhắn tin tự triển khai cho nhu cầu người dùng và hội nhóm nhỏ có nhu cầu.
Hình 2.3 Logo ứng dụng Signal, Element và Let’s Chat theo thứ tự
Phân tích yêu cầu hệ thống
Phát triển được một ứng dụng nhắn tin trên nền tảng web cung cấp hệ thống vận hành tối ưu cho việc xử lý số lượng người dùng cao và kết nối đồng thời với nhiều người dùng
Cung cấp cho người dùng một nền tảng giao tiếp thời gian thực cho việc trao đổi tin nhắn văn bản và các tập tin đa phương tiện với đầy đủ các tính năng cho đa số nhu cầu sử dụng
Hệ thống cung cấp khả năng khởi chạy đơn giản và khả năng tự triển khai, vận hành cho các nhu cầu cá nhân, tổ chức
Người dùng có nhu cầu giao tiếp, trao đổi nhanh dữ liệu qua mạng
Các hội nhóm có số lượng người dùng lớn cần giao tiếp liên tục
Các hội nhóm, tổ chức có nhu cầu tự vận hành hoặc có yêu cầu bảo mật dữ liệu trong môi trường đóng kín hoặc riêng tư
3.2.1.3 Yêu cầu công nghệ & mục tiêu phát triển
- Đối với backend : Sử dụng các framework có hiệu năng cao, hỗ trợ việc thiết kế HTTP endpoint cho các yêu cầu cơ bản và Websocket endpoint cho các yêu cầu thời gian thực, cùng với hỗ trợ các tính năng bảo mật đường truyền và bảo vệ dữ liệu.
- Đối với hệ thống vận hành: áp dụng các biện pháp vận hành container, cân bằng tải và bảo mật kết nối giữa các services; cùng với việc cung cấp các công cụ theo dõi nhằm đảm bảo backend vận hành như mong muốn, cũng như phát hiện lỗi nếu có.
- Đối với frontend : Sử dụng framework có cấu trúc, tốc độ phát triển nhanh cho việc demo và thiết kế MVP.
- Phát triển được một hệ thống hoàn chỉnh đầy đủ các thành phần backend,frontend và vận hành được trên máy chủ cũng như trên các nền tảng đám mây.
- Source code phát triển có độ sạch sẽ cao, các thành phần được phân tách rõ ràng, cũng như được chú thích và cung cấp hướng dẫn cho nhu cầu tự vận hành của người dùng
3.2.1.4.1 Đăng ký và xác thực người dùng
- Người dùng có thể tạo tài khoản với tên người dùng và mật khẩu để truy cập và sử dụng ứng dụng
- Các tài khoản mới được cấp quyền User mặc định để sử dụng các chức năng quản lý thông tin cá nhân, cũng như các chức năng của hội nhóm và tin nhắn về sau.
3.2.1.4.2 Quản lý thông tin người dùng
- Người dùng có thể cung cấp và sửa đổi thông tin cho hồ sơ của họ, bao gồm tên người dùng, mã số nhận dạng, ảnh đại diện và mô tả người dùng
- Người dùng có quyền chỉnh sửa tên tài khoản, mật khẩu và email liên kết
- Người dùng có thể yêu cầu xóa tài khoản, đi cùng với xóa các thông tin cá nhân của người dùng
- Tạo nhóm : người dùng có thể tạo nhóm riêng và được cấp quyền quản trị viên (admin) cho nhóm đó
- Xem thông tin nhóm : người dùng có thể xem tên, ảnh đại diện, người tham gia nhóm và trạng thái của họ, cùng một vài thông tin khác
- Chỉnh sửa thông tin nhóm : o Các admin nhóm có thể thay đổi tên nhóm, ảnh đại diện nhóm và cài đặt hiển thị của nhóm (nhóm công khai hoặc riêng tư) o Admin nhóm có thể chọn các thành viên khác trong nhóm cùng làm admin
- Tham gia nhóm : người dùng có thể tự tham gia các nhóm công khai qua liên kết nhóm, và có thể được mời tham gia các nhóm riêng tư qua lời mời của admin
- Rời nhóm : các thành viên nhóm có thể tự rời nhóm hoặc được admin mời khỏi nhóm
3.2.1.5 Quản lý tin nhắn và trao đổi thông tin
Người tham gia nhóm có thể gửi nhiều loại tin nhắn vào nhóm:
- Tin nhắn văn bản, đường liên kết
- Icon, biểu tượng cảm xúc
- Tập tin đa phương tiện (file, hình ảnh, video, …)
Người tham gia nhóm có thể ghim tin nhắn của bản thân hoặc của người khác
Người dùng sẽ nhận được thông báo theo thời gian thực về:
Kết quả của các thao tác quan trọng (tạo nhóm mới, thêm/xoá thành viên khỏi nhóm, …)
Lời mời tham gia nhóm mới
Các tin nhắn mới trong nhóm
Các thông báo quan trọng từ hệ thống (cập nhật, bảo trì, …)
Người dùng có thể tìm kiếm thông tin của những người dùng khác qua tên
Người dùng có thể tìm kiếm các tin nhắn trong nhóm qua cụm từ tìm kiếm
3.2.1.8 Quản lý bảo mật thông tin & bảo mật chức năng
Người dùng khi đăng nhập thành công sẽ được cấp access token và refresh token để xác thực cho các tính năng trong hệ thống
Các nhóm riêng tư sẽ không thể được tìm kiếm từ bên ngoài, và người dùng không thể tham gia các nhóm riêng tư mà cần phải chấp nhận lời mời của Admin nhóm đó
3.2.1.9 Quản lý vai trò trong ứng dụng
User : người dùng đã đăng ký tài khoản trên hệ thống User là vai trò cơ bản trong hệ thống, có quyền xem, chỉnh sửa thông tin cá nhân, tham gia các nhóm công khai hoặc các nhóm riêng tư có lời mời, xem thông tin và gửi tin nhắn vào các nhóm đã tham gia, gửi báo cáo vi phạm, …
Group Admin (admin nhóm) : bao gồm các quyền của User, cùng với đó có quyền thêm / bớt người trong nhóm, chỉnh sửa thông tin và cài đặt hiển thị của nhóm, gán / bỏ gán quyền admin cho các thành viên nhóm
Application Admin (admin hệ thống) : có quyền xem thông tin nhật ký hệ thống, theo dõi các thông số hệ thống, xem / thực thi hành động đối với các báo cáo vi phạm, thêm người khác làm admin hệ thống
3.2.2 Yêu cầu phi chức năng
3.2.2.1 Hiệu suất hệ thống (Performance)
Hệ thống cần được tối ưu về cả phần mềm lẫn phần cứng để chịu được tải trọng giao tiếp cao, số lượng người dùng kết nối cùng lúc lớn trong giới hạn sức mạnh phần cứng
Thiết kế kiến trúc hệ thống
3.3.1 Tổng quan kiến trúc hệ thống
3.3.1.1 Các thành phần hệ thống
Client : các kết nối từ người dùng thông qua giao diện Frontend Tùy vào chức năng người dùng sử dụng mà Frontend tạo ra loại kết nối tương ứng (HTTP hoặc Websocket)
Load balancer : điểm quản lý các kết nối giữa client và server, cũng như thực hiện cân bằng tải (chia đều kết nối ra các thành phần song song) trong hệ thống
API backend : cung cấp API endpoint cho các tính năng cơ bản của ứng dụng, quản lý kiểm tra dữ liệu đầu vào và đầu ra, thực hiện truy vấn và xử lý dữ liệu từ các database cluster
Websocket backend : cung cấp Websocket endpoint cho các tính năng gửi
& nhận thông báo tin nhắn theo thời gian thực
Các database : các cụm cơ sở dữ liệu được sử dụng riêng cho từng loại dữ liệu cụ thể.
Notification queue : hàng chờ dữ liệu (message queue) để cập nhật các thông báo mới của người dùng.
File server : service quản lý việc upload và tải file
3.3.1.2 Sơ đồ kiến trúc hệ thống
Hình 3.1 Software Architecture Diagram tổng quan
3.3.2 Chi tiết kiến trúc hệ thống
3.3.2.1 Bộ công nghệ áp dụng
3.3.2.1.1 Giao diện người dùng (Frontend)
Framework: ReactJS được áp dụng để tái sử dụng các thành phần giao diện và tối ưu hiệu suất
ReactJS là một thư viện JavaScript mạnh mẽ được phát triển bởi Facebook, chuyên dụng trong việc xây dựng giao diện người dùng hiệu quả và linh hoạt Điểm nổi bật của ReactJS là khả năng tạo ra các thành phần (components) tái sử dụng, giúp quản lý mã nguồn một cách dễ dàng và duy trì ứng dụng một cách hiệu quả Nó sử dụng mô hình "one-way data binding" để tối ưu hóa hiệu suất và cung cấp một cách tiếp cận linh hoạt trong quản lý trạng thái ứng dụng
Framework: FastAPI (Python) cùng các thư viện hỗ trợ và thiết lập môi trường
FastAPI là một micro-framework có hiệu suất cao với kiến trúc dựa trên Starlette và Pydantic Việc FastAPI sử dụng chuẩn ASGI (Asynchronous
Server Gateway Interface) hỗ trợ code bất đồng bộ cho server interface so với các Python framework khác chỉ sử dụng WSGI, cùng với việc cung cấp sẵn các biện pháp kiểm tra dữ liệu đầu vào qua Pydantic đã giúp FastAPI có hiệu năng vận hành nhanh hơn đáng kể.
Hình 3.2 Benchmark FastAPI so với các framework phổ biến khác [4]
Framework: Echo để nâng cấp kết nối HTTP và Gorilla Websocket (Golang)
Echo là một HTTP framework tối giản và hiệu năng ổn định trên nền tảng của Golang, cung cấp khả năng router nhanh và các middleware (mã trung gian) có sẵn cho các nhu cầu đặc biệt.
Gorilla Websocket là một thư viện Websocket nằm trong bộ Gorilla Toolkit được Golang gợi ý sử dụng Thư viện cung cấp cấu trúc Websocket hoàn thiện và đi kèm với documentation chi tiết, thích hợp cho việc thiết kế kết nối Websocket ổn định và có cấu trúc.
Hình 3.3 Bộ công cụ HTTP Gorilla Toolkit
- PostgreSQL : dùng để chứa các dữ liệu về thông tin của người dùng
PostgreSQL là 1 hệ thống quản trị cơ sở dữ liệu SQL miễn phí và mã nguồn mở tiên tiến nhất hiện nay PostgreSQL tích hợp nhiều tính năng hỗ trợ các câu truy vấn phức tạp, quản lý commit/rollback transaction và khả năng bảo mật đáng tin cậy (SCRAM-SHA256, LDAP, …).
Với việc được phát triển từ rất sớm, PostgreSQL có tính ổn định và độ tin
- Redis: dùng để thiết kế bộ nhớ đệm quản lý token kết nối và lưu trữ thông tin đệm của người dùng
Hình 3.4 Sử dụng Redis trong việc thiết kế bộ nhớ đệm
Redis là 1 cơ sở dữ liệu lưu trữ dữ liệu trên RAM (in-memory) dưới dạng key-value rất mạnh mẽ và phổ biến Redis là một lựa chọn tuyệt vời cho nhu cầu lưu trữ các dữ liệu với tốc độ cao cũng như để tối ưu hệ thống, nhờ vào tốc độ đọc dữ liệu từ RAM và cấu trúc key-value có độ phức tạp thuật toán thấp
Ngoài ra Redis cũng hỗ trợ các tính năng lưu dữ liệu vào ổ đĩa, cũng như sao lưu dữ liệu nếu cần thiết.
- ScyllaDB: dùng để lưu trữ tin nhắn người dùng, dữ liệu hội nhóm và các dữ liệu thời gian thực khác (thông báo, tin nhắn ghim, …)
ScyllaDB là 1 hệ thống cơ sở dữ liệu NoSQL phân tán dạng node mạnh mẽ được kế thừa từ Cassandra, một hệ thống cơ sở dữ liệu dạng node cực kỳ phổ biến khác.
Với thiết kế theo dạng một chuỗi các node kết nối thành vòng tròn, một hệ thống ScyllaDB có thể biến đổi theo thời gian bằng cách thêm/bớt node Dữ liệu được phân bổ vào các node dựa trên Partition Key , với các phần tử dữ liệu có cùng Partition Key sẽ nằm ở chung node (các tin nhắn của cùng một nhóm, các nhóm đã tham gia của cùng một người, …), từ đó tăng tốc việc truy vấn dữ liệu.
Cùng với đó, việc thiết kế theo dạng node giúp cho ScyllaDB có các tính năng bảo toàn dữ liệu như Replication Factor (RF - một phần tử dữ liệu nằm ở nhiều node) và Consistency Level (CL - số lượng phần tử dữ liệu tối thiểu để xác nhận dữ liệu tồn tại) rất mạnh mẽ.
Hình 3.5 Cấu trúc ScyllaDB với 5 node, RF=3 và CL=1
3.3.2.1.5 Các công nghệ hỗ trợ
- RabbitMQ là hệ thống thiết kế message queue hiệu suất, nhỏ gọn và khả năng tải cao, thích hợp cho việc truyền tải thông tin giữa các service.
- NGINX là một trong những công cụ reverse proxy và load balancer phổ biến nhất hiện tại, với khả năng chuyển hướng đa dạng và xác thực, bảo mật thông tin đa dạng.
3.3.2.2 Phân tích kiến trúc hệ thống
Nền tảng của kiến trúc cơ sở dữ liệu của đồ án được dựa trên định lý CAP
(CAP Theorem) của Eric Brewer: Khi lỗi phân vùng mạng (network partition failure) xảy ra, hệ thống phải lựa chọn một trong hai phương án sau đây:
- Hủy tác vụ: điều này làm giảm tính khả dụng (availability) nhưng đảm bảo tính nhất quán (consistency) của hệ thống.
- Tiếp tục thực hiện tác vụ: đảm bảo tính khả dụng nhưng có thể dẫn đến không nhất quán trong dữ liệu trả về.
Hình 3.6 Biểu đồ Venn của CAP Theorem
Hệ cơ sở dữ liệu của đồ án được chia thành 2 loại chính:
- Relational (SQL): được sử dụng chính để lưu trữ các thông tin cá nhân của người dùng Sử dụng SQL database sẽ đảm bảo consistency của dữ liệu cá nhân, từ đó đảm bảo nền tảng để thực hiện các chu trình phức tạp hơn Cùng với đó, các nền tảng SQL database thường có khả năng bảo mật tốt hơn nhờ cấu trúc chắc chắn và thời gian phát triển lâu dài hơn. Nhóm sử dụng PostgreSQL làm relational database chính.
- Non-relational (NoSQL): được sử dụng để lưu trữ các thông tin về tin nhắn cũng như hội nhóm của người dùng, cũng như dùng để thiết kế bộ nhớ đệm và tối ưu truy vấn Nhóm sử dụng 2 loại non-relational database chính: o Database phân tán dạng node (ScyllaDB) để đảm bảo khả năng mở rộng cũng như tốc độ truy vấn cao do dữ liệu được lưu trữ thành các partition Cùng với đó database phân tán cũng hỗ trợ việc tạo nhiều bản sao dữ liệu ở các node khác nhau nhằm đảm bảo tính Availability cho hệ thống nếu một vài node có vấn đề. o Database dạng key-value (Redis) để làm vùng nhớ đệm cho các thao tác lặp lại và ít thay đổi, do cấu trúc nhỏ gọn và độ phức tạp truy vấn thấp.
Thiết kế chức năng
3.4.1 Thiết kế quản lý dữ liệu
Các entity màu xanh đậm là dữ liệu người dùng được lưu trên PostgreSQL, với PK (Primary Key) là khoá chính và FK (Foreign Key) là khoá ngoại.
Các entity màu xanh nhạt là dữ liệu liên quan đến hội nhóm được lưu trên ScyllaDB cluster, với P (Partition Key) xác định phân vùng và C (Clustering Key) xác định thứ tự sắp xếp các dòng dữ liệu bên trong 1 partition.
3.4.1.2 Các thuộc tính của entity
Type Name Data Type Nullable
PK id int False username str False password str False email str False
FK accountinfo_id int True
Type Name Data Type Nullable
PK id int False name str True identifier int False description str True time_created timestamp True
FK accountattachment_id int True
Type Name Data Type Nullable
PK id int False filename str True
Type Name Data Type Nullable
P id UUID False name Text False description Text True visibility Boolean False time_created DateTime False
Type Name Data Type Nullable
C (DESC) id UUID False description Text True time_created DateTime True
Type Name Data Type Nullable
C (DESC) group_id UUID False
C (DESC) time_created DateTime False notify Boolean False role Text False
Type Name Data Type Nullable
C (DESC) accountinfo_id Integer False
C (DESC) time_created DateTime False notify Boolean False role Text False
Type Name Data Type Nullable
C (DESC) time_created DateTime False
C (DESC) group_id UUID False group_name Text True accountinfo_name Text True type Text False content Text False
Type Name Data Type Nullable
C (DESC) time_created DateTime False
C (DESC) accountinfo_id Integer False group_name Text True accountinfo_name Text True type Text False content Text False
Type Name Data Type Nullable
C (DESC) time_created DateTime False
C (DESC) accountinfo_id Integer False accountinfo_name Text True group_name Text True type Text False content Text False time_pinned DateTime False
Type Name Data Type Nullable
C (DESC) filename Text False time_created DateTime False
Type Name Data Type Nullable
C (DESC) time_created DateTime False
C (DESC) group_id UUID False accountinfo_id_sender Integer False content Text False
Type Name Data Type Nullable
C (DESC) group_id UUID False
C (DESC) time_created DateTime False
3.4.2.2 Đặc tả các Use case
Bảng 3.14 Bảng danh sách các Use case
ID Tiêu đề Vai trò sử dụng Tổng quan Use case
UC01 Tạo tài khoản Guest Người mới có thể tạo tài khoản với các thông tin cá nhân để sử dụng hệ thống
UC02 Đăng nhập Guest Người mới có thể đăng nhập vào tài khoản cá nhân để sử dụng hệ thống
UC03 Chỉnh sửa tài khoản
User Người dùng có thể chỉnh sửa thông tin tài khoản, cung cấp các thông tin như tên người dùng và ảnh đại diện
UC04 Tạo nhóm mới User Người dùng có thể tạo nhóm mới với các thông tin cung cấp như tên nhóm, chi tiết và cài đặt công khai nhóm
UC05 Tham gia nhóm công khai
User Người dùng có thể tự tham gia các nhóm công khai
UC06 Xác nhận lời mời nhóm riêng tư
User Người dùng có thể chấp nhận / từ chối lời mời tham gia nhóm
UC07 Gửi tin nhắn vào nhóm
User Người dùng có thể gửi tin nhắn tới các nhóm đã tham gia
UC08 Gửi tập tin vào nhóm
User Người dùng có thể gửi các tập tin đa phương tiện tới các nhóm đã tham gia
UC09 Rời nhóm User Người dùng có thể rời khỏi các nhóm đã tham gia
UC10 Xoá nhóm Group Owner Chủ nhóm có thể xoá các nhóm họ sở hữu
Group Owner Chủ nhóm có thể cấp quyền Admin cho thành viên trong nhóm hoặc thu hồi quyền của các Admin
UC12 Chỉnh sửa thông tin nhóm
Admin nhóm có thể chỉnh sửa các thông tin nhóm như tên, giới thiệu nhóm và cài đặt riêng tư nhóm
UC13 Chỉnh sửa người tham gia nhóm
Admin nhóm có thể mời người khác tham gia nhóm hoặc đuổi thành viên ra khỏi nhóm
Bảng 3.15 UC01 – Tạo tài khoản
Description Người mới có thể tạo tài khoản với các thông tin cá nhân để sử dụng hệ thống
Trigger Người dùng chọn chức năng Đăng ký từ trang chủ
Type External (do Actor kích hoạt)
1 Người dùng chọn chức năng Đăng ký
2 Người dùng chọn loại hình đăng nhập bằng tài khoản tự cung cấp
(chuyển đến bước 3a) hoặc bằng tài khoản bên thứ ba (chuyển đến bước 3b)
3a.1 Người dùng cung cấp thông tin tài khoản bao gồm email, tên tài khoản và mật khẩu
3a.2 Người dùng xác nhận mật khẩu đã nhập 3a.3 Hệ thống xác minh thông tin hợp lệ (chuyển đến bước 4)
3b.1 Người dùng được chuyển hướng đến trang đăng nhập của bên thứ ba 3b.2 Bên thứ ba xác nhận thông tin hợp lệ và trả về thông tin người dùng cho hệ thống (chuyển đến bước 4)
4 Hệ thống tạo tài khoản mới và thông báo cho người dùng
Tài khoản người dùng được khởi tạo thành công
Exceptions 3a.1 Nếu tên tài khoản và gmail đã được sử dụng, hệ thống hiển thị nhắc nhở tới người dùng và hoãn quá trình 3a.2 Nếu hai mật khẩu nhập vào không khớp, hệ thống hiển thị nhắc nhở cho người dùng và hoãn quá trình
3b.2 Nếu người dùng đăng nhập bên thứ ba không thành công, hệ thống thông báo tới người dùng và quay lại đầu quá trình
Description Người mới có thể đăng nhập vào tài khoản cá nhân để sử dụng hệ thống
Trigger Người dùng chọn chức năng Đăng nhập từ trang chủ
Type External (do Actor kích hoạt)
1 Người dùng chọn chức năng Đăng nhập
2 Người dùng chọn loại hình đăng nhập bằng tài khoản tự cung cấp
(chuyển đến bước 3a) hoặc bằng tài khoản bên thứ ba (chuyển đến bước 3b)
3a Người dùng cung cấp thông tin tài khoản bao gồm tên tài khoản/email và mật khẩu (chuyển đến bước 4)
3b.1 Người dùng được chuyển hướng đến trang đăng nhập của bên thứ ba 3b.2 Bên thứ ba xác nhận thông tin hợp lệ và trả về thông tin người dùng cho hệ thống (chuyển đến bước 4)
4 Hệ thống xác minh thông tin hợp lệ
5 Hệ thống thông báo thành công, khởi tạo token đăng nhập và gửi cho người dùng
Người dùng nhận được token đăng nhập
Exceptions 4 Nếu cặp tên tài khoản/gmail và mật khẩu không xuất hiện trong hệ thống, hệ thống hiển thị thông báo tới người dùng và quay lại đầu quá trình
4 Nếu người dùng đăng nhập bên thứ ba không thành công, hệ thống thông báo tới Guest và quay lại đầu quá trình
3.4.2.2.4 UC03 – Chỉnh sửa tài khoản
Bảng 3.17 UC03 – Chỉnh sửa tài khoản
Description Người dùng có thể chỉnh sửa thông tin tài khoản, cung cấp các thông tin như tên người dùng và ảnh đại diện
Trigger Người dùng mở tính năng Chỉnh sửa thông tin cá nhân
Type External (do Actor kích hoạt)
Người dùng đăng nhập hợp lệ và token đăng nhập còn thời gian hiệu lực
1 Người dùng chọn chức năng Chỉnh sửa thông tin cá nhân
2 Hệ thống hiện các mục để:
Chỉnh sửa thông tin tổng quan người dùng gồm tên, mã số định danh và giới thiệu (chuyển đến bước 3a)
Thông tin đăng nhập gồm mật khẩu (chuyển đến bước 3b)
Chỉnh sửa ảnh đại diện (chuyển đến bước 3c)
3a Người dùng nhập các thông tin cá nhân (tên, mã số định danh và giới thiệu) muốn cập nhật và nhấn nút xác nhận (chuyển đến bước 4)
3b Người dùng nhập mật khẩu cũ, mật khẩu mới, nhập lại mật khẩu mới và nhấn nút xác nhận (chuyển đến bước 4)
3c.1 Website hiện hộp thoại chọn file cho người dùng 3c.2 Người dùng chọn ảnh đại diện muốn đổi và nhấn nút xác nhận
4 Hệ thống xác nhận thông tin mới hợp lệ, cập nhật và thông báo cho người dùng
Thông tin người dùng được cập nhật thành công
Exceptions 3a Nếu tên/mã số định danh mới để trống, hệ thống hiển thị nhắc nhở không hợp lệ cho User và hoãn quá trình 3a Nếu cặp tên và mã số định danh mới đã được sở hữu, hệ thống hiển thị thông báo cho User và hoãn quá trình
3b.1 Nếu hai mật khẩu nhập vào không khớp, hệ thống hiển thị nhắc nhở cho Guest và hoãn quá trình
Bảng 3.18 UC04 – Tạo nhóm mới
Description Người dùng có thể tạo nhóm mới với các thông tin cung cấp như tên nhóm, chi tiết và cài đặt công khai nhóm
Trigger Người dùng nhấn nút Tạo nhóm mới ở trang chủ
Type External (do Actor kích hoạt)
Pre- conditions Người dùng đăng nhập hợp lệ và token đăng nhập còn thời gian hiệu lực
Normal course 1 Người dùng nhấn nút Tạo nhóm mới ở trang chủ
2 Hệ thống hiện ra hộp thoại Tạo nhóm
3 Người dùng nhập vào tên nhóm, giới thiệu nhóm và chế độ riêng tư, và nhấn nút xác nhận
4 Hệ thống tạo nhóm mới với các thông tin người dùng cung cấp, gán người dùng làm Chủ nhóm (Creator) và thông báo thành công cho người dùng
Nhóm mới được tạo thành công với người dùng làm Chủ nhóm
Exceptions 3 Nếu tên nhóm để trống, hệ thống thông báo với người dùng và hoãn quá trình
3.4.2.2.6 UC05 – Tham gia nhóm công khai
Bảng 3.19 UC05 – Tham gia nhóm công khai
Description Người dùng có thể tự tham gia các nhóm công khai
Trigger Người dùng thực hiện chức năng tìm kiếm trên trang chủ
Type External (do Actor kích hoạt)
Người dùng đăng nhập hợp lệ và token đăng nhập còn thời gian hiệu lực
1 Người dùng chọn chức năng tìm kiếm trên trang chủ
2 Người dùng nhập cụm từ để tìm kiếm nhóm
3 Hệ thống lấy ra các nhóm công khai có tên nhóm chứa cụm từ tìm kiếm và hiện ra danh sách cho người dùng
4 Người dùng nhấn vào nhóm muốn tham gia và nhấn nút Tham gia nhóm
5 Hệ thống cập nhật người dùng thành người tham gia của nhóm đó và thông báo thành công cho người dùng
Người dùng trở thành thành viên của nhóm
Exceptions 2 Nếu cụm từ quá ngắn ( 99%
Hình 4.6 Kết quả Breakpoint Test của testcase signin.js
- Số lượng người dùng thực hiện tối đa (vus) : 9999 (vượt qua ngưỡng bài test)
- Lý do testcase dừng lại: hoàn thành ngưỡng bài test
Hình 4.7 Kết quả Breakpoint Test của testcase ws-connect.js
- Số lượng người thực hiện tối đa (vus) : 785
- Lý do testcase dừng lại: vượt quy định 95% số lượng HTTP request hoàn thành dưới 500ms
Hình 4.8 Kết quả Breakpoint Test của testcase http-read.js
- Số lượng người dùng tối đa mà bài test hoàn thành được (vus_max) : 500
- Tỉ lệ thành công (checks) : 98.74%
- Số lượng request mỗi giây (http_reqs) : 87.9 req/s
- Thời gian xử lý HTTP trung bình (http_req_duration - med) : 57.3 ms
- Thời gian xử lý request trung bình (http_req_duration) : 146.55ms
Hình 4.9 Kết quả Load Test của testcase http-read.js
- ws-read-write.js (Breakpoint): o Số lượng người dùng thực hiện tối đa (vus) : 1338 o Lý do testcase dừng lại: vượt quy định Tỉ lệ thành công WS > 99%
Hình 4.10 Kết quả Breakpoint Test của testcase ws-read-write.js
- ws-read-write.js (Load): o Số lượng người dùng tối đa mà bài test hoàn thành được (vus_max) : 1000 o Số lượng tin nhắn WS gửi đi mỗi giây (ws_msgs_sent) : 156.6 msg/s o Số lượng tin nhắn WS nhận được mỗi giây (ws_msgs_received) :
Hình 4.11 Kết quả Load Test của testcase ws-read-write.js
- http-ws-read-write (Breakpoint): o Số lượng người dùng thực hiện tối đa (vus) : 841 o Lý do testcase dừng lại: vượt quy định 95% số lượng HTTP request hoàn thành dưới 500ms
Hình 4.12 Kết quả Breakpoint Test của testcase http-ws-read-write.js
- http-ws-read-write (Load): o Số lượng người dùng tối đa mà bài test hoàn thành được (vus_max) : 800 o Số lượng tin nhắn WS gửi đi mỗi giây (ws_msgs_sent) : 167.5 msg/s o Số lượng tin nhắn WS nhận được mỗi giây (ws_msgs_received) :
584 msg/s o Thời gian xử lý HTTP trung bình (http_req_duration - med) : 9.6 ms
Hình 4.13 Kết quả Load Test của testcase http-ws-read-write.js
- Tổng quan kết quả thu được: Đối với các bài test chi tiết: o Hệ thống có thể hỗ trợ tối đa 9 người dùng đăng nhập cùng lúc với thuật toán hashing chậm o Hệ thống hỗ trợ 10000+ kết nối WS song song (đủ cho yêu cầu đề bài)
Nhóm đã thử nghiệm ở các thông số cao hơn nhằm đạt yêu cầu, nhưng đa phần hệ thống khi chạy Load Test sẽ bị ngắt giữa chừng do vượt các quy định cơ bản Bảng thông số tổng hợp:
Hình 4.1 Bảng thông số tổng hợp thu được
Số lượng kết nối WS đồng thời Số lượng tin nhắn WS/s Số lượng kết nối HTTP/s
1000 (http-ws-read-write.js)
167.5 (http-ws-read-write.js)
- Một vài điểm rút ra được: o Các điểm tắc nghẽn đa số xảy ra ở API Backend module, phổ biến nhất là một vài request có thời gian xử lý cao bất thường làm chỉ số p(95) tăng cao testcase ngắt giữa chừng. o Việc cache dữ liệu là rất quan trọng đối với các dữ liệu có tần suất truy vấn cao (dữ liệu người dùng khi xác thực token, …). o Phải cẩn trọng khi thực hiện các chỉnh sửa đối với các thành phần được chia sẻ trong nhiều luồng xử lý song song khác nhau (goroutine) nhằm tránh gây xung đột tài nguyên, ví dụ như client- connection map
Hình 4.14 Lock và Unlock connection map trong quá trình đọc/ghi (WS Backend) o Đôi khi có tình trạng request thất bại không rõ nguyên nhân (như ởLoad Test của testcase http-read.js) cần phải khắc phục.