Tiết kiệm chi phí vận hành VPS: Hướng dẫn khai thác tối đa tài nguyên với CyberPanel
Khi website "chết lâm sàng" vì thiếu RAM (hay mình tưởng thế)
Làm vận hành, có lẽ cảm giác "sập" là một trong những thứ mình chai lì nhất. Nhưng cái lần mà website của khách hàng cứ ì ạch rồi đột ngột không truy cập được vào một tối thứ Ba, lúc 20h00 ấy, mình vẫn thấy hơi run.
Khách cứ gọi, email tới tấp báo website chậm như rùa, rồi sau đó là
503 Service Unavailable. Mình ban đầu nghĩ ngay đến kịch bản quen thuộc: code bug mới đẩy lên, hoặc một cuộc tấn công DDoS nhỏ nào đó làm quá tải server. Thế là mình cứ cắm mặt vào kiểm tra log Apache/Nginx (mình dùng OpenLiteSpeed thật ra), rồi xem lượng truy cập Realtime trên Analytics, hay thậm chí là debug từng phần của ứng dụng.
Một tiếng rưỡi trôi qua, đến 21h30, sau khi quét một lượt hết cả ứng dụng lẫn tình hình mạng, mình mới nhìn kỹ hơn vào log hệ thống trên VPS. Và ôi thôi, nó rõ ràng như ban ngày:
kernel: cgroup: memory usage is at 1024MB, OOM target is 1024MB
kernel: Out of memory: Kill process 12345 (php) score 999 or sacrifice child
kernel: Killed process 12345 (php) total-vm:2048MB, anon-rss:1024MB, file-rss:0MB
Là nó rồi! OOM – Out Of Memory. Cái chết đau đớn nhất của một tiến trình khi hệ thống hết RAM để cấp phát. Nhưng lạ cái, con VPS mình đang dùng có tận 4GB RAM cơ mà. Sao 1024MB đã lăn ra chết rồi? Mình cứ đinh ninh là RAM dư dả lắm, chắc chắn không phải do thiếu bộ nhớ đâu.
Thật ra, câu chuyện không đơn giản là VPS còn RAM hay không. Nó là về cách CyberPanel - và cụ thể hơn là OpenLiteSpeed - quản lý tài nguyên từng website con thông qua `cgroups v2`.
Cái bẫy 1024MB RAM mặc định của CyberPanel
Đến 22h00, mình bắt đầu "bới" lại toàn bộ cấu hình gói hosting của khách hàng trên CyberPanel. Mình nhớ là hồi setup mình có chọn gói Basic hay gì đó, nhưng không đào sâu vào mấy cái thông số giới hạn.
Lúc ấy, mình cứ nghĩ là các gói hosting trên panel chỉ để "làm cảnh" hoặc phân biệt tên gọi thôi, chứ tài nguyên thì cứ dựa vào con số RAM/CPU thật của VPS mà chạy. Đây là một "vết xước" khá ngớ ngẩn mà mình hay gặp hồi mới chuyển từ cPanel sang, vì cPanel có cách quản lý tài nguyên khác, ít "nghiêm khắc" với từng account như CyberPanel.

Thật ra, CyberPanel sử dụng `cgroups v2` của Linux để tạo ra một môi trường "đóng" cho từng website (hoặc gói hosting). Điều này giống như việc mỗi website có một VPS nhỏ của riêng nó, với các giới hạn tài nguyên được định sẵn.
Từ tài liệu chính thức của CyberPanel mình đọc được, các giới hạn mặc định khá "chặt chẽ":
- Memory Limit (MB):
1024 MB - CPU Cores:
1 - I/O Limit (MB/s):
10 MB/s - Inode Limit:
400000 - Max Connections (concurrent PHP connections):
10 - Process Soft Limit:
400 - Process Hard Limit:
500
Tức là, dù VPS mình có 4GB RAM đi chăng nữa, thì website kia vẫn chỉ được cấp tối đa 1GB RAM để hoạt động. Nếu nó vượt quá, y như rằng `kernel` sẽ ra tay "kết liễu" bằng một thông báo OOM kill như mình đã thấy.
Cái quan trọng nữa, như tài liệu Resource Limits Guide for CyberPanel có nhắc (mình đang đọc cái bản gốc từ Knowledge Base của họ, có lẽ là phiên bản 2.4.4 hoặc tương đương), là để các giới hạn này có hiệu lực, bạn phải đảm bảo đã "Check "Enforce Disk Limits" checkbox in package settings." Cái tên hơi lừa tình tí, vì nó không chỉ áp dụng cho mỗi Disk mà là toàn bộ giới hạn tài nguyên.
Sửa lỗi cấu hình: từ "đoán sai" đến "tối ưu"
Sau khi đã hiểu ra căn nguyên, đến khoảng 23h00, mình bắt đầu điều chỉnh lại gói hosting. Mình tăng Memory Limit của gói đó lên 2048 MB và CPU Cores lên 2. Mình cũng "suýt" nữa là nâng cấp gói VPS với giá cao hơn từ nhà cung cấp (mình thường hay so giá bên Hetzner vì quen), trong khi vấn đề chỉ nằm ở một cái cấu hình nhỏ trong panel thôi. May mà kịp phanh lại.
Quan trọng hơn, có một chi tiết ngớ ngẩn mà mình quên béng đi: "Limits are applied immediately when a website is created or a package is modified (website needs recreation for new limits to apply)".
Nghĩa là, sau khi sửa gói hosting, mình **phải Recreate Website** thì những giới hạn mới đó mới có hiệu lực.
cd /usr/local/lsws/conf/vhosts/<domain>/ && rm -rf conf.d/
cyberpanel createWebsite --domain <domain> --package <package_name> --adminUser <username> --adminPass <password> --email <email@example.com>
Cái lệnh thứ hai này thật ra là một ví dụ cho việc tạo mới, nhưng ý mình là bạn phải có thao tác để "áp lại" cấu hình cho website. Thông thường, trên giao diện CyberPanel có nút "Recreate Website" sau khi bạn thay đổi Package.
Sau khi làm xong các bước này, mình ngồi chờ, cứ 15 phút lại kiểm tra log hệ thống một lần.
00h30: Website "sống" lại, bài học "đắt"
Đến đúng 00h30, website của khách hàng hoạt động ổn định trở lại. Lượng RAM tiêu thụ tăng lên nhưng không còn thấy dấu hiệu OOM kill nữa. Traffic đổ về bình thường, các tiến trình PHP chạy mượt mà.
Thật ra, nhiều khi vấn đề không phải do code hay server yếu, mà chỉ là mình chưa hiểu đúng cách các công cụ đang vận hành thôi. Bài học này không chỉ giúp mình tránh được việc phải nâng cấp VPS không cần thiết (tiết kiệm kha khá chi phí cho khách và cả mình), mà còn là một lời nhắc nhở về việc không nên tin tưởng dashboard một cách mù quáng – kiểu "VPS còn RAM mà sao sập?". Lúc nào cũng cần đào sâu vào tầng cơ chế, nhất là với những hệ thống mạnh mẽ như CyberPanel và OpenLiteSpeed với `cgroups v2` của nó.