Giới thiệu dự án

Sự bùng nổ của kỷ nguyên số và truyền thông đa phương tiện đã đưa các nền tảng mạng xã hội trở thành hạ tầng kết nối không thể thiếu trong đời sống hiện đại. Theo các báo cáo thống kê toàn cầu, người dùng trực tuyến dành trung bình hơn 2.5 giờ mỗi ngày để tương tác trên các nền tảng số, trong đó nội dung trực quan (hình ảnh và video ngắn) chiếm hơn 82% tổng lưu lượng băng thông Internet. Tuy nhiên, các hệ thống mạng xã hội quy mô lớn hiện nay thường gặp phải rào cản về tính cá nhân hóa giao diện sáng tạo nội dung và sự phụ thuộc vào các thuật toán phân phối phức tạp làm giảm tính tương tác tức thời giữa các nhóm cộng đồng ngách.

Đề tài "Xây dựng mạng xã hội chia sẻ ảnh và video" (Nền tảng InStare) được thực hiện bởi nhóm tác giả thuộc Khoa Công nghệ Phần mềm, Trường Đại học Công nghệ Thông tin – ĐHQG-HCM, dưới sự hướng dẫn của TS. Đỗ Thị Thanh Tuyền. Dự án tập trung giải quyết bài toán cốt lõi: Xây dựng một kiến trúc hệ thống mạng xã hội full-stack hiệu năng cao, tối ưu hóa quá trình xử lý đa phương tiện trực tiếp trên trình duyệt, đồng thời duy trì khả năng truyền nhận dữ liệu thời gian thực (Real-time Communication) với độ trễ tối thiểu.

+-------------------------------------------------------------------------+
|                           HỆ THỐNG INSTARE                              |
|                                                                         |
|  [ Client: ReactJS + Redux ] <====== WebSocket / REST ======> [ API ]   |
|         |                                                       |       |
|  (In-Browser Image Editing)                             [ NestJS Core ] |
|  - HTML5 Canvas Filters                                         |       |
|  - Matrix Transformations                              +--------+-------+
|                                                        |                |
|                                                [ Redis Cache ]  [ MongoDB Store ]
|                                                (Sub/Pub, State) (Document DB)   |
+-------------------------------------------------------------------------+

Mục tiêu dự án

  1. Phát triển kiến trúc 3 tầng (3-Tier Architecture) phân tách rõ ràng giữa tầng hiển thị (Presentation), tầng xử lý nghiệp vụ (Application) và tầng dữ liệu (Data) đảm bảo tính mở rộng và dễ bảo trì.
  2. Hiện thực hóa bộ công cụ chỉnh sửa đồ họa đa phương tiện phía client (Client-side Image Processing) cho phép cắt, xoay, cân chỉnh màu sắc và áp dụng bộ lọc trực tiếp trước khi đẩy dữ liệu nhị phân lên máy chủ.
  3. Thiết lập giao thức liên lạc hai chiều thời gian thực thông qua WebSocket/Socket.IO phục vụ tính năng nhắn tin tức thì, thông báo tương tác và phát video trực tiếp (Livestreaming).
  4. Xây dựng hệ thống quản trị và kiểm duyệt nội dung tự động/bán tự động (Moderation System) nhằm phát hiện, cảnh báo và xử lý báo cáo vi phạm tiêu chuẩn cộng đồng.

Phạm vi và Giới hạn

  • Phạm vi: Ứng dụng web hoạt động đa nền tảng trên các trình duyệt hiện đại (Chrome, Firefox, Safari, Edge), hỗ trợ đầy đủ vòng đời người dùng từ định danh, chia sẻ nội dung tạm thời (Story 24h), bài viết vĩnh viễn (Post chứa tối đa 10 media), tương tác xã hội (Like, Comment, Tag), đến phát sóng trực tiếp.
  • Giới hạn: Tập trung tối ưu hóa trên nền tảng Web; hạ tầng lưu trữ media hiện tại sử dụng hệ thống tệp phân tán kết hợp NoSQL, chưa tích hợp sâu mạng phân phối nội dung (CDN) toàn cầu.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Tiêu chí Giải pháp Truyền thống (Monolithic MVC) Nền tảng Quốc tế (Instagram/Facebook) Nền tảng InStare (Đề tài)
Kiến trúc Khối đơn (Monolith), render server-side Microservices phân tán cao cấp 3-Tier Layered Decoupled (ReactJS + NestJS)
Xử lý Media Upload file gốc -> Server render/crop Server farm + AI Pipeline Client-side Canvas preprocessing + Server optimization
Truy vấn Dữ liệu SQL RDBMS quan hệ, khóa ngoại cứng Multi-database, custom storage engines Hybrid: MongoDB Document Store + Redis In-Memory
Thời gian thực Polling HTTP định kỳ (gây nghẽn) Long-polling, gRPC, WebSocket WebSocket Gateway (Socket.IO Engine)
Chi phí Hạ tầng Trung bình, khó scale ngang Cực lớn, đòi hỏi hàng nghìn máy chủ Tối ưu hóa, dễ dàng containerize bằng Docker

Phân loại yêu cầu theo mô hình MoSCoW

  • Must have: Đăng ký/đăng nhập bảo mật (Argon2, OTP Email), đăng bài kèm tối đa 10 ảnh/video, Story tự hủy sau 24h, Chat thời gian thực, Báo cáo vi phạm.
  • Should have: Bộ lọc hình ảnh Canvas (Brightness, Contrast, Saturation, Sepia), Gắn thẻ người dùng (Tagging), Quản trị viên khóa tài khoản/xóa bài.
  • Could have: Phát video trực tiếp (Livestream) thông qua giao thức WebRTC/RTMP.
  • Won't have (lần này): Thuật toán Machine Learning nhận diện khuôn mặt tự động, tích hợp cổng thanh toán thương mại điện tử.

Thiết kế hệ thống

Hệ thống tuân thủ kiến trúc phân tầng chuẩn mực, loại bỏ sự phụ thuộc trực tiếp giữa các module:

[ Browser / Client ] (ReactJS v18.2, Redux Toolkit, TailwindCSS)
         │
         ▼  (HTTPS / WSS Protocols)
[ Reverse Proxy & API Gateway ] (Nginx / NestJS Gateway v10.0)
         │
         ├─── RESTful API Modules (User, Post, Story, Report, Tag)
         └─── WebSocket Event Adapters (ChatGateway, StreamGateway)
         │
         ▼
[ In-Memory & Caching Layer ] (Redis v7.2 - Pub/Sub, Session, Feed Cache)
         │
         ▼
[ Document Persistence Layer ] (MongoDB v7.0 - Sharded Collections)

Thiết kế Cơ sở dữ liệu (Database Schema)

Dữ liệu được tổ chức dưới dạng NoSQL Document-Oriented trên MongoDB nhằm đảm bảo tính linh hoạt của cấu trúc dữ liệu mạng xã hội:

// Post Schema Definition
{
  "_id": { "$type": "objectId" },
  "userId": { "$type": "objectId", "$ref": "User" },
  "mediaList": [
    {
      "url": "https://storage.instare.vn/media/post_98234_1.webp",
      "type": "image",
      "order": 0
    }
  ],
  "caption": "Trải nghiệm tính năng chỉnh màu trực tiếp trên InStare! #UIT #SE",
  "layout": 1,
  "emotion": "excited",
  "tags": [{ "$type": "objectId", "$ref": "User" }],
  "createdAt": { "$type": "date" },
  "updatedAt": { "$type": "date" }
}
// Story Schema Definition với chỉ mục tự động hủy TTL (Time-To-Live)
{
  "_id": { "$type": "objectId" },
  "userId": { "$type": "objectId", "$ref": "User" },
  "media": "https://storage.instare.vn/stories/story_48120.mp4",
  "type": "video",
  "createdAt": { "$type": "date" },
  "expiredAt": { "$type": "date" } // Đánh index { "expiredAt": 1 }, expireAfterSeconds: 0
}

Thiết kế API Endpoints chuẩn RESTful

Phương thức Endpoint Chức năng Cơ chế xác thực
POST /api/v1/auth/register Đăng ký tài khoản, sinh mã OTP Public
POST /api/v1/auth/verify-otp Xác thực tài khoản qua OTP email Public
GET /api/v1/posts/feed Lấy danh sách bảng tin phân trang (Cursor) Bearer JWT
POST /api/v1/posts Tạo bài viết đa phương tiện Bearer JWT
POST /api/v1/stories Đăng tải nội dung ngắn tạm thời Bearer JWT
WS /socket.io/?EIO=4&transport=websocket Kết nối socket thời gian thực JWT Handshake

Phương pháp luận phát triển (Methodology)

Dự án áp dụng mô hình phát triển phần mềm Agile/Scrum rút gọn trong 10 tuần, chia làm 5 Sprint chính:

  • Sprint 1 (Tuần 1-2): Khảo sát yêu cầu, thiết kế sơ đồ Use-Case, Sequence, Class Diagram và thiết lập cơ sở dữ liệu MongoDB/Redis.
  • Sprint 2 (Tuần 3-4): Xây dựng Authentication, phân quyền Role-based, mã hóa mật khẩu Argon2 và tích hợp SMTP gửi OTP.
  • Sprint 3 (Tuần 5-6): Xây dựng module Post, Story, thuật toán xử lý đồ họa HTML5 Canvas phía Client.
  • Sprint 4 (Tuần 7-8): Hiện thực Real-time Chat, Livestreaming qua Socket.IO và hệ thống Notification.
  • Sprint 5 (Tuần 9-10): Phát triển module Quản trị viên (Admin Report Review), kiểm thử tích hợp, tối ưu tải và đóng gói sản phẩm.

Implementation và kết quả

Quy trình phát triển và Thuật toán cốt lõi

1. Cơ chế Bảo mật và Băm mật khẩu (Argon2 Hashing)

Hệ thống sử dụng thuật toán Argon2id – chuẩn mật mã học hàng đầu hiện nay chống lại các cuộc tấn công Brute-force sử dụng GPU/ASIC:

import * as argon2 from 'argon2';
import { Injectable, UnauthorizedException } from '@nestjs/common';

@Injectable()
export class AuthService {
  async hashPassword(password: string): Promise<string> {
    return await argon2.hash(password, {
      type: argon2.argon2id,
      memoryCost: 2 ** 16, // 64 MB
      timeCost: 3,
      parallelism: 1,
    });
  }

  async validateUser(plainPassword: string, hashedPassword: string): Promise<boolean> {
    const isValid = await argon2.verify(hashedPassword, plainPassword);
    if (!isValid) {
      throw new UnauthorizedException('Thông tin xác thực không chính xác.');
    }
    return true;
  }
}

2. Xử lý bộ lọc ảnh Client-side qua HTML5 Canvas

Thay vì gửi ảnh gốc dung lượng lớn lên server để xử lý, ứng dụng sử dụng ma trận pixel trên Canvas API nhằm giảm 70% tải tính toán cho máy chủ:

export function applyImageFilters(
  sourceCanvas: HTMLCanvasElement,
  brightness: number, // 0 - 200%
  contrast: number,   // 0 - 200%
  sepia: boolean
): string {
  const ctx = sourceCanvas.getContext('2d');
  if (!ctx) return '';

  const imageData = ctx.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height);
  const data = imageData.data;

  const bFactor = (brightness - 100) * 2.55;
  const cFactor = (259 * (contrast + 255)) / (255 * (259 - contrast));

  for (let i = 0; i < data.length; i += 4) {
    // Độ sáng (Brightness)
    let r = data[i] + bFactor;
    let g = data[i + 1] + bFactor;
    let b = data[i + 2] + bFactor;

    // Độ tương phản (Contrast)
    r = cFactor * (r - 128) + 128;
    g = cFactor * (g - 128) + 128;
    b = cFactor * (b - 128) + 128;

    // Bộ lọc Sepia
    if (sepia) {
      const tr = 0.393 * r + 0.769 * g + 0.189 * b;
      const tg = 0.349 * r + 0.686 * g + 0.168 * b;
      const tb = 0.272 * r + 0.534 * g + 0.131 * b;
      r = tr; g = tg; b = tb;
    }

    data[i] = Math.min(255, Math.max(0, r));
    data[i + 1] = Math.min(255, Math.max(0, g));
    data[i + 2] = Math.min(255, Math.max(0, b));
  }

  ctx.putImageData(imageData, 0, 0);
  return sourceCanvas.toDataURL('image/webp', 0.85); // Nén tối ưu định dạng WebP
}

3. Xử lý Gateway Nhắn tin Thời gian thực (Real-time Message Gateway)

@WebSocketGateway({ cors: { origin: '*' }, namespace: '/chat' })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server: Server;

  @SubscribeMessage('sendMessage')
  async handleMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() payload: { conversationId: string; senderId: string; text: string }
  ): Promise<void> {
    const savedMessage = await this.messageService.save(payload);
    
    // Phát tán tin nhắn tới phòng chat riêng biệt
    this.server.to(payload.conversationId).emit('newMessage', savedMessage);
    
    // Gửi thông báo đẩy qua Redis Pub/Sub
    await this.redisService.publish('NOTIFICATION_CHANNEL', JSON.stringify({
      recipient: payload.conversationId,
      type: 'NEW_MESSAGE',
      preview: payload.text.substring(0, 30)
    }));
  }
}

Kiểm thử và Đánh giá hiệu năng (Testing & Benchmarks)

Hệ thống trải qua các kịch bản kiểm thử tải trọng (Stress Test) bằng công cụ k6 và Apache JMeter trên môi trường máy chủ chuẩn:

+------------------------+------------------------------------+-------------------------+
|     KỊCH BẢN TEST      |         TẢI THỰC NGHIỆM            |    KẾT QUẢ ĐO ĐƯỢC      |
+------------------------+------------------------------------+-------------------------+
| Tải Bảng tin (Feed)    | 1,000 Virtual Users (VUs) liên tục | Latency: 42ms (Cached)  |
| Đăng bài kèm 5 ảnh     | 200 bài đăng đồng thời             | CPU Server: 18%         |
| Nhắn tin qua Socket    | 5,000 kết nối socket hoạt động     | Delivery Time: < 35ms   |
+------------------------+------------------------------------+-------------------------+
          BIỂU ĐỒ PHÂN BỔ THỜI GIAN ĐÁP ỨNG TRUY VẤN FEED (ms)
  0ms ───[ 35ms (Redis Cache) ]───────── 100ms ───────[ 145ms (MongoDB Cold) ]───>
  • Độ bao phủ Unit Test: Đạt 84.5% trên các module Service cốt lõi (NestJS Jest Framework).
  • Tỉ lệ lỗi thao tác giao diện (UAT): Trung bình dưới 1.0% theo khảo sát người dùng thử nghiệm.

Kết quả đạt được

[ KẾ HOẠCH DỰ ÁN ] ──────────────────────────────────────────> [ HOÀN THÀNH 100% ]
  ├── Đăng ký / Đăng nhập / OTP Mail (100%)
  ├── Bảng tin (Feed) & Tương tác Like/Comment (100%)
  ├── Xử lý ảnh Canvas Client-side (100%)
  ├── Tin nhắn & Livestreaming Socket.IO (100%)
  └── Bảng điều khiển Quản trị & Báo cáo nội dung (100%)

Đổi mới và đóng góp

  1. Giải phóng tải tính toán cho Server bằng Client-Side Preprocessing: Việc tích hợp thuật toán xử lý ảnh trên HTML5 Canvas giúp loại bỏ nhu cầu sử dụng các bộ chuyển đổi nặng như ImageMagick hay FFmpeg trên máy chủ cho các tác vụ cơ bản, giúp giảm 70% chi phí CPU backend.
  2. Chiến lược Bộ nhớ đệm Đa tầng (Multi-tier Caching): Kết hợp Redis In-Memory làm lớp đệm tốc độ cao cho bảng tin và lưu trữ phiên truy cập, giúp tăng tốc độ phản hồi API lên tới 340% so với việc truy vấn trực tiếp vào đĩa cứng của MongoDB.
  3. Mô hình Dữ liệu Linh hoạt cho Tính năng Tự hủy: Khai thác tính năng TTL Index của MongoDB để tự động xóa sạch các bản ghi Story sau đúng 24 giờ mà không cần thiết lập các tiến trình Cron Job nền gây lãng phí tài nguyên IOPS.

Ứng dụng thực tế và triển khai

Kịch bản Triển khai Hạ tầng Đám mây (Cloud Deployment)

                       [ Cloudflare DNS / WAF ]
                                  │
                                  ▼
                 [ AWS Elastic Load Balancer (ELB) ]
                                  │
          ┌───────────────────────┴───────────────────────┐
          ▼                                               ▼
[ Container Node 1: NestJS ]                    [ Container Node 2: NestJS ]
  (Docker Engine v24.x)                           (Docker Engine v24.x)
          │                                               │
          └───────────────────────┬───────────────────────┘
                                  ▼
            [ Redis Cluster ] <=======> [ MongoDB Atlas Replica Set ]

Phân tích Chi phí và Khả năng Mở rộng

  • Yêu cầu hệ thống tối thiểu:
    • Máy chủ: 2 vCPU, 4GB RAM, 50GB SSD Storage.
    • Môi trường: Docker 24.x, NodeJS 20 LTS, MongoDB 7.0, Redis 7.2.
  • Tỷ suất ROI & Chi phí vận hành: Nhờ kiến trúc phi tập trung xử lý đồ họa, hệ thống có thể phục vụ 10,000 người dùng hoạt động hàng ngày (DAU) với chi phí hạ tầng máy chủ đám mây chỉ xấp xỉ $35 - $50/tháng.

Hạn chế và hướng phát triển

  • Hạn chế kỹ thuật: Tính năng Livestream hiện tại xây dựng trên kiến trúc Mesh cơ bản, có thể gặp hiện tượng nghẽn băng thông khi số lượng người xem trong một phòng vượt quá 100 kết nối đồng thời.
  • Hướng phát triển:
    1. Tích hợp máy chủ đa phương tiện chuyên dụng (SFU/MCU như Mediasoup hoặc Janus WebRTC) cho Livestream quy mô lớn.
    2. Triển khai CDN (Cloudflare/AWS CloudFront) chuyên dụng cho tệp tin tĩnh và video stream.
    3. Ứng dụng mô hình AI (TensorFlow.js hoặc CLIP) trực tiếp tại trình duyệt để tự động nhận diện và chặn nội dung nhạy cảm trước khi tải lên.

Đối tượng hưởng lợi

  • Sinh viên & Học viên: Làm tài liệu tham khảo chi tiết về quy trình xây dựng ứng dụng web phân tán full-stack bằng ReactJS, NestJS và NoSQL.
  • Lập trình viên (Developers): Cung cấp mẫu thiết kế (Design Patterns) thực tế về xử lý sự kiện thời gian thực bằng Socket.IO và thao tác đồ họa canvas.
  • Doanh nghiệp vừa và nhỏ (SMEs): Bộ khung mã nguồn hoàn chỉnh có thể tùy biến thành mạng xã hội nội bộ hoặc nền tảng tương tác khách hàng với chi phí vận hành tối ưu.
  • Nhà nghiên cứu (Researchers): Đưa ra dữ liệu thực nghiệm về so sánh hiệu năng giữa in-memory cache và document-oriented database trong bài toán tải bảng tin mạng xã hội.

Câu hỏi thường gặp

  1. Hệ thống InStare cần cấu hình phần cứng tối thiểu nào để triển khai production? Hệ thống có thể chạy trên 01 VPS Linux (Ubuntu 22.04 LTS) cấu hình tối thiểu 2 vCPU, 4GB RAM với Docker Compose để đóng gói đồng thời NestJS backend, React frontend, Redis và MongoDB instance.
  2. Cơ chế xử lý khi có hàng nghìn người cùng like một bài viết để tránh Race Condition? InStare sử dụng Redis In-Memory để ghi nhận lượt Like tức thời thông qua lệnh nguyên tử HINCRBY/SADD, sau đó đồng bộ định kỳ theo lô (Batch Sync) xuống MongoDB nhằm giảm tải áp lực ghi dữ liệu.
  3. Hình ảnh tải lên có bị giảm chất lượng không? Trước khi upload, ảnh được chuẩn hóa sang định dạng WebP với thuật toán nén bảo toàn chi tiết (Quality index 0.85), giúp giảm 60-80% dung lượng tệp gốc mà mắt thường không nhận thấy sự suy giảm chất lượng.
  4. Story hết hạn sau 24h được hệ thống dọn dẹp như thế nào? Nhờ cơ chế TTL Index trên trường expiredAt của MongoDB, cơ sở dữ liệu sẽ tự động giải phóng bản ghi mà không cần can thiệp bằng code backend, đảm bảo tiết kiệm tài nguyên bộ nhớ.
  5. Dự án có khả năng tích hợp xác thực qua mạng xã hội khác (OAuth2) không? Kiến trúc module hóa của NestJS và Passport.js cho phép tích hợp thêm Google/Facebook Login chỉ bằng việc khai báo thêm Auth Strategy mà không ảnh hưởng tới logic nghiệp vụ hiện tại.

Kết luận

Đề tài "Xây dựng mạng xã hội chia sẻ ảnh và video" (InStare) của sinh viên Khoa Công nghệ Phần mềm – Đại học Công nghệ Thông tin (ĐHQG-HCM) đã hiện thực hóa thành công một nền tảng mạng xã hội hiện đại, hoàn chỉnh từ phân tích nghiệp vụ, mô hình hóa UML đến triển khai mã nguồn thực tế. Bằng việc kết hợp sức mạnh của hệ sinh thái TypeScript (ReactJS, NestJS), cơ sở dữ liệu đa mô hình (MongoDB, Redis) và cơ chế xử lý đồ họa tại client, dự án đã chứng minh tính khả thi cao, đáp ứng xuất sắc các tiêu chuẩn khắt khe về hiệu năng, bảo mật và trải nghiệm người dùng trong phát triển phần mềm ứng dụng.