Quay lại danh sách
Tin tức công nghệ

Tối ưu hóa VPS Ubuntu để Đạt Throughput Mạng Tối Đa Cho Ứng Dụng Real-Time Chat 1 Triệu User

28 tháng 5, 2026

Giới Thiệu: Thách Thức Hệ Thống Khi Scale 1 Triệu WebSocket Connection

Xây dựng một ứng dụng Real-time Chat phục vụ vài ngàn người dùng là một bài toán đơn giản. Tuy nhiên, khi quy mô hệ thống tăng lên đến 1 triệu người dùng kết nối đồng thời (Concurrent Users), mọi chuyện sẽ hoàn toàn thay đổi. Đối với các ứng dụng real-time sử dụng WebSocket hoặc Server-Sent Events (SSE), thách thức lớn nhất không nằm ở năng lực tính toán của CPU (Compute-bound) mà nằm ở băng thông mạng, bộ nhớ RAM và giới hạn của hệ điều hành (I/O-bound).

Mặc định, cấu hình kernel của Ubuntu Server được thiết kế cho các tác vụ tổng quát, không tối ưu cho việc duy trì hàng triệu kết nối TCP mở liên tục (Persistent Connections). Nếu không can thiệp sâu vào network stack, hệ thống của bạn sẽ nhanh chóng gặp phải các lỗi nghiêm trọng như Connection refused, Too many open files, hoặc cạn kiệt tài nguyên bộ nhớ đệm socket, dẫn đến sập diện rộng. Bài viết này sẽ hướng dẫn bạn từng bước tối ưu hóa chuyên sâu một VPS Ubuntu để đạt throughput mạng tối đa.

1. Nâng Cao Giới Hạn File Descriptors Toàn Hệ Thống

Trong hệ điều hành Linux, "mọi thứ đều là file" (Everything is a file). Mỗi một kết nối mạng TCP/WebSocket thiết lập đến server sẽ được quản lý dưới dạng một File Descriptor (FD). Theo cấu hình mặc định của Ubuntu, giới hạn số lượng FD cho mỗi process thường chỉ dừng lại ở con số 1024 hoặc 4096. Để phục vụ 1 triệu user, con số này phải được mở rộng đáng kể.

Tăng giới hạn hệ thống trong /etc/sysctl.conf

Đầu tiên, chúng ta cần cấu hình lại số lượng file tối đa mà toàn bộ hệ thống lõi có thể mở bằng cách cấu hình tham số fs.file-max. Thêm dòng sau vào file:

fs.file-max = 2097152

Tăng giới hạn cho từng Session và User trong /etc/security/limits.conf

Tiếp theo, bạn cần đảm bảo user chạy ứng dụng (ví dụ: www-data hoặc user của ứng dụng Node.js/Go) được phép mở hơn 1 triệu kết nối cùng lúc. Hãy thêm cấu hình sau:

* soft nofile 1048576
* hard nofile 1048576
root soft nofile 1048576
root hard nofile 1048576
Lưu ý quan trọng: Tham số soft limit là cấu hình hiện tại mà process có thể đạt tới, còn hard limit là mức trần tối đa mà user có thể tự nâng lên mà không cần quyền root. Chúng ta đặt cả hai mức lên trên 1 triệu (1,048,576) để đảm bảo không bị nghẽn cổ chai tại đây.

2. Tối Ưu Hóa Bộ Tham Số Kernel TCP/IP (Sysctl Tuning)

Đây là trái tim của quá trình tối ưu hóa. Chúng ta cần chỉnh sửa file /etc/sysctl.conf để thay đổi cách Ubuntu xử lý luồng dữ liệu mạng, quản lý bộ nhớ đệm của socket và tái sử dụng các kết nối cũ.

Quản lý bộ nhớ đệm TCP (TCP Buffer Size)

Mỗi kết nối TCP yêu cầu một lượng bộ nhớ RAM nhất định cho hàng đợi nhận (Receive queue) và gửi (Send queue). Nếu cấu hình quá lớn, server sẽ hết sạch RAM khi có 1 triệu user. Nếu quá nhỏ, throughput mạng sẽ bị giảm do mất gói tin hoặc cửa sổ trượt (TCP Window) bị thu hẹp.

# Định dạng: min default max (tính bằng bytes)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

Tối ưu hóa hàng đợi kết nối (Connection Backlog)

Khi hàng vạn user cùng kết nối vào hệ thống trong một giây (hiện tượng thắt nút cổ chai khi giờ cao điểm), hệ thống cần một hàng đợi đủ lớn để chứa các yêu cầu chưa được xử lý xong (Handshake phase).

  • net.core.somaxconn: Định nghĩa số lượng kết nối tối đa nằm trong hàng đợi chờ accept của ứng dụng. Hãy tăng lên ít nhất là 65535.
  • net.ipv4.tcp_max_syn_backlog: Số lượng kết nối nửa mở (SYN_RECV) tối đa được phép xếp hàng. Đặt giá trị này lên 65535 để chống lại việc quá tải kết nối và các cuộc tấn công SYN Flood nhẹ.
  • net.core.netdev_max_backlog: Số lượng gói tin tối đa được xếp hàng đợi ở tầng card mạng xử lý trước khi chuyển lên tầng CPU. Giá trị khuyến nghị: 65535.

Tái sử dụng trạng thái TIME_WAIT

Khi các cổng mạng đóng lại, chúng rơi vào trạng thái TIME_WAIT trong vòng 60 giây để đảm bảo không bị lẫn lộn các gói tin cũ. Khi có hàng triệu kết nối liên tục đóng mở, các port này sẽ nhanh chóng bị cạn kiệt (Ephemeral Port Exhaustion). Hãy kích hoạt tính năng tái sử dụng:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535

Bằng cách mở rộng dải port từ 1024 đến 65535, server sẽ có hơn 64,000 cổng cục bộ cho mỗi địa chỉ IP nguồn để kết nối tới dịch vụ downstream (như cơ sở dữ liệu hoặc microservices khác).

3. Cấu Hình Tối Ưu Hóa Reverse Proxy (Nginx / HAProxy)

Thông thường, bạn sẽ không để ứng dụng chat (Node.js, Go, Java) tiếp xúc trực tiếp với Internet mà sẽ đi qua một Reverse Proxy như Nginx hoặc HAProxy để xử lý SSL/TLS Termination và Load Balancing. Bản thân các proxy này cũng cần được cấu hình đồng bộ.

Cấu hình Nginx tối ưu cho WebSocket

Trong file cấu hình nginx.conf, hãy chắc chắn rằng bạn đã tối ưu hóa các tham số sau:

worker_processes auto;
worker_rlimit_nofile 1048576;

events {
    worker_connections 500000;
    use epoll;
    multi_accept on;
}

Trong khối http, hãy thêm cấu hình hỗ trợ WebSocket giữ kết nối lâu dài (Keepalive):

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

# Hỗ trợ HTTP/1.1 và Upgrade header cho WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Việc đặt worker_rlimit_nofile tương thích với giới hạn hệ thống giúp Nginx không bao giờ gặp lỗi ngắt quãng kết nối giữa chừng với client.

4. Giám Sát, Đo Lường Và Kiểm Thử Tải (Load Testing)

Sau khi đã áp dụng toàn bộ các cấu hình trên bằng lệnh sudo sysctl -p, việc tiếp theo là phải thực hiện kiểm thử để chứng minh hệ thống thực sự có khả năng gánh 1 triệu người dùng đồng thời.

Bạn nên sử dụng các công cụ chuyên dụng cho việc giả lập kết nối real-time với số lượng lớn như Tsung hoặc Artillery. Hãy chuẩn bị một cụm máy client (Distributed Load Testing) vì một máy client duy nhất không bao giờ đủ port và tài nguyên để tạo ra 1 triệu kết nối WebSocket.

Các thông số cần theo dõi liên tục:

  1. RAM Usage: Kiểm tra xem trung bình mỗi kết nối tiêu tốn bao nhiêu KB RAM. Với 1 triệu user, nếu mỗi user tốn 30KB, bạn cần ít nhất 30GB RAM trống chỉ dành cho network buffer.
  2. Soft IRQs (Software Interrupts): Sử dụng lệnh top hoặc htop để kiểm tra xem các nhân CPU có bị quá tải do xử lý ngắt mạng từ card mạng hay không. Nếu có, cần cấu hình Receive Side Scaling (RSS) để phân phối tải đều ra các nhân.
  3. Conntrack Table: Hệ thống tường lửa (iptables/ufw) theo dõi trạng thái kết nối thông qua module nf_conntrack. Cần tăng net.netfilter.nf_conntrack_max lên tương ứng (ví dụ: 1048576) để tránh rớt gói tin.

Kết Luận

Tối ưu hóa một hệ thống Ubuntu gánh tải 1 triệu user chat real-time không phải là phép màu từ một dòng lệnh duy nhất, mà là sự tinh chỉnh đồng bộ từ Phần cứng (RAM, Card mạng) -> Kernel OS (TCP/IP parameters) -> Ứng dụng Proxy (Nginx) -> Mã nguồn của bạn. Áp dụng chính xác các bước tinh chỉnh trên sẽ giúp doanh nghiệp của bạn tiết kiệm tối đa chi phí hạ tầng VPS, tăng tính ổn định của sản phẩm và mang lại trải nghiệm real-time mượt mà tuyệt đối cho người dùng cuối.

Tối ưu hóa VPS Ubuntu để Đạt Throughput Mạng Tối Đa Cho Ứng Dụng Real-Time Chat 1 Triệu User | DPTCloud