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

Tối Ưu Hóa Linux Kernel Cho Node.js VPS: Bí Quyết Đạt 100.000 Kết Nối WebSockets Đồng Thời

29 tháng 5, 2026

Giới Thiệu: Thử Thách Của Bài Toán C100K Và WebSockets

Trong kỷ nguyên của các ứng dụng thời gian thực (real-time applications), việc duy trì hàng chục, thậm chí hàng trăm nghìn kết nối đồng thời là một yêu cầu bắt buộc đối với các kỹ sư hệ thống. Khác với kiến trúc HTTP truyền thống (nơi các kết nối ngắn hạn và kết thúc nhanh chóng), WebSockets thiết lập các kết nối dài hạn (persistent connections) và giữ chúng mở liên tục. Điều này đặt ra một áp lực khổng lồ lên hệ điều hành nền tảng.

Node.js, với mô hình Single-Threaded và Event-Driven phi chặn (Non-blocking I/O), là một ứng cử viên xuất sắc cho các tác vụ I/O cao. Tuy nhiên, dù mã nguồn Node.js của bạn có được tối ưu đến đâu, hiệu năng của hệ thống vẫn sẽ bị giới hạn bởi cấu hình mặc định của Linux Kernel. Các thiết lập mặc định này thường được tối ưu hóa cho các máy chủ đa mục đích thông thường, chứ không phải cho bài toán C100K (100,000 kết nối đồng thời). Bài viết này sẽ hướng dẫn bạn từng bước can thiệp sâu vào nhân Linux để giải phóng toàn bộ sức mạnh của VPS.

1. Vượt Qua Giới Hạn File Descriptors (Định Danh Tập Tin)

Trong hệ điều hành Linux, mọi thứ đều là tập tin (Everything is a file), và một kết nối mạng (Socket) cũng không ngoại lệ. Mỗi kết nối WebSockets mở ra sẽ tiêu tốn một File Descriptor (FD). Theo mặc định, Linux giới hạn số lượng FD tối đa mà một tiến trình có thể mở ở mức rất thấp (thường là 1024).

Tối ưu hóa ở cấp độ toàn hệ thống

Để cho phép hệ thống xử lý hơn 100.000 kết nối, chúng ta cần nâng giới hạn FD toàn hệ thống bằng cách chỉnh sửa tệp /etc/sysctl.conf:

fs.file-max = 2097152

Tối ưu hóa ở cấp độ User và Process

Tiếp theo, bạn cần cấu hình tệp /etc/security/limits.conf để cho phép người dùng chạy ứng dụng Node.js (ví dụ: nodeuser) có quyền mở số lượng FD lớn:

nodeuser soft nofile 200000
nodeuser hard nofile 200000
Lưu ý: Giới hạn 'soft' là cấu hình hiện tại có thể tăng lên bởi ứng dụng, trong khi 'hard' là trần tối đa mà user không thể vượt qua nếu không có quyền root. Chúng ta đặt mức 200.000 để dự phòng cho 100.000 kết nối WebSockets cộng với các file hệ thống khác.

Cấu hình Systemd Service

Nếu bạn quản lý ứng dụng Node.js bằng Systemd (khuyến nghị cho môi trường sản xuất), hãy chắc chắn rằng dịch vụ của bạn áp dụng các giới hạn này bằng cách thêm dòng sau vào file cấu hình dịch vụ (.service):

[Service]
LimitNOFILE=200000

2. Tối Ưu Hóa Hệ Thống Mạng (Networking Stack Tuning)

Khi hàng chục nghìn kết nối đổ vào cùng một lúc, hàng đợi mạng (networking queues) mặc định của Linux sẽ nhanh chóng bị tràn, dẫn đến tình trạng rớt gói tin (packet loss) và tăng độ trễ (latency).

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

Chúng ta cần tăng kích thước hàng đợi để nhân Linux có thể giữ các kết nối đang chờ xử lý trước khi Node.js chấp nhận chúng (accept). Thêm các cấu hình sau vào /etc/sysctl.conf:

  • net.core.somaxconn = 65535: Tăng số lượng kết nối tối đa trong hàng đợi của socket lắng nghe.
  • net.ipv4.tcp_max_syn_backlog = 65535: Tăng số lượng kết nối TCP "half-open" tối đa (giai đoạn SYN_RCVD trong quá trình bắt tay 3 bước).

Mở rộng dải Ephemeral Ports

Mỗi kết nối outbound hoặc kết nối qua proxy ngược (như Nginx đứng trước Node.js) yêu cầu một cổng cục bộ (ephemeral port). Mặc định dải cổng này khá hẹp. Hãy mở rộng nó:

net.ipv4.ip_local_port_range = 1024 65535

Cấu hình này cung cấp hơn 64.000 cổng. Để đạt 100.000 kết nối trên một IP duy nhất kết nối với Nginx, bạn sẽ cần cấu hình Nginx lắng nghe trên nhiều cổng hoặc nhiều IP local alias.

3. Quản Lý Bộ Nhớ RAM Cho TCP Sockets

Mỗi kết nối WebSockets duy trì một lượng bộ nhớ đệm nhất định cho việc đọc (read) và ghi (write) dữ liệu. Nếu cấu hình bộ nhớ quá lớn, VPS của bạn sẽ nhanh chóng rơi vào tình trạng Out of Memory (OOM) khi đạt 100K kết nối.

Chúng ta cần tối ưu hóa không gian bộ nhớ TCP bằng cách định cấu hình lại các giá trị buffer trong /etc/sysctl.conf:

net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

Các giá trị này đại diện cho [min, default, max] tính bằng bytes. Việc giữ mức min ở 4096 bytes giúp tiết kiệm dung lượng RAM đáng kể cho các kết nối WebSockets nhàn rỗi (idle connections), cho phép hệ thống co giãn linh hoạt dựa trên tải thực tế.

4. Tái Sử Dụng Kết Nối Và Cơ Chế TCP Keepalive

Để ngăn chặn việc tích tụ các kết nối trong trạng thái TIME_WAIT (gây cạn kiệt tài nguyên), cần cho phép Linux tái sử dụng các socket này một cách an toàn:

net.ipv4.tcp_tw_reuse = 1

Đồng thời, cấu hình lại các thông số TCP Keepalive để nhanh chóng phát hiện và ngắt các kết nối "chết" (zombie connections) từ phía máy khách đã mất mạng đột ngột:

net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5

Với cấu hình này, nếu sau 300 giây kết nối không có hoạt động, hệ thống sẽ gửi các gói tin kiểm tra mỗi 15 giây. Nếu sau 5 lần thử thất bại, kết nối sẽ lập tức bị đóng, giải phóng tài nguyên cho hệ thống.

5. Áp Dụng Cấu Hình Và Kiểm Thử (Benchmark)

Sau khi đã thêm toàn bộ cấu hình vào tệp /etc/sysctl.conf, hãy chạy lệnh sau với quyền root để các thay đổi có hiệu lực ngay lập tức mà không cần khởi động lại VPS:

sudo sysctl -p

Kiểm tra thực tế với K6 hoặc Artillery

Để chứng minh hệ thống đã sẵn sàng cho mốc 100K kết nối, bạn nên thực hiện kiểm thử tải (Load Testing) bằng các công cụ chuyên dụng như Artillery hoặc K6 từ một hoặc nhiều máy chủ kiểm thử độc lập ngoại vi. Giám sát lượng RAM tiêu thụ bằng lệnh free -m và số lượng kết nối đang mở bằng:

ss -s

Kết Luận

Tối ưu hóa Linux Kernel cho các ứng dụng hiệu năng cao như Node.js WebSockets không đơn thuần là việc tăng các con số cấu hình, mà là nghệ thuật cân bằng giữa tài nguyên phần cứng (CPU, RAM) và khả năng xử lý của phần mềm. Bằng cách áp dụng các tinh chỉnh về File Descriptors, Network Stack, và TCP Buffers được hướng dẫn ở trên, VPS của bạn hoàn toàn đủ khả năng chinh phục cột mốc 100.000 kết nối WebSockets đồng thời một cách mượt mà và ổn định.

Tối Ưu Hóa Linux Kernel Cho Node.js VPS: Bí Quyết Đạt 100.000 Kết Nối WebSockets Đồng Thời | DPTCloud