Tôi không viết bài này như một review tiêu cực về REGXA, cũng không định bảo ai nên hay không nên mua VPS của họ. Đây đơn giản là một ngày làm việc của tôi với tư cách developer.
Tôi chuyển một workload bình thường sang VPS KVM có 2 vCPU, 2 GB RAM và 60 GB NVMe. Nginx đang chạy. Backend cũng chạy. Nhưng máy hoạt động như thể bị overload nghiêm trọng: request dồn lại, TLS chậm đi, connection giữ mở quá lâu và có request mất hơn hai phút mới trả về HTTP 504.
CPU accounting đã thay đổi hướng điều tra
Giả thuyết đầu tiên rất hiển nhiên: một thứ gì đó trong VPS đang ăn CPU. Sau đó tôi chạy mpstat.
Average CPU steal: 92.58%
CPU 0 steal: 90.62%
CPU 1 steal: 94.57%
CPU user: 4.02%
CPU system: 1.47%
CPU iowait: 0.41%
CPU idle: 0.53%
Các sample riêng lẻ liên tục cho thấy khoảng 89–98% steal. CPU pressure cũng ở mức cực cao:
CPU PSI some avg10: 79.47
CPU PSI some avg60: 75.32
CPU PSI some avg300: 76.31
Load average: 5.85 / 5.75 / 5.73
Đây chỉ là máy có hai vCPU. Linux có các process runnable đang chờ CPU. Con số quan trọng không phải mức sử dụng CPU thông thường của application, mà là %steal.
CPU usage cao và CPU steal là hai vấn đề khác nhau
Nếu application của tôi thực sự đang dùng hết processor, tôi sẽ kỳ vọng user hoặc system cao. Thay vào đó VPS trông gần như thế này:
user: 4%
system: 1%
steal: 93%
CPU steal là khoảng thời gian virtual CPU đã sẵn sàng chạy nhưng không được hypervisor schedule. Vì vậy khi tôi nói VPS bị lấy mất CPU time, tôi dùng đúng nghĩa kỹ thuật trong virtualization. Tôi không thể chứng minh REGXA cố tình chuyển những physical core vốn độc quyền dành cho tôi sang khách hàng khác, và guest metric cũng không thể chứng minh ý định. Điều tôi có thể chứng minh là guest liên tục có công việc sẵn sàng chạy nhưng không nhận được CPU scheduling time.
Tôi loại bỏ toàn bộ production traffic
Vẫn còn một phản biện hợp lý: có thể chính workload của tôi gây ra vấn đề. Vì vậy tôi loại bỏ biến đó. Tôi chuyển workload đang hoạt động sang nơi khác, dừng production traffic đến VPS này, chờ queue hết rồi đo lại.
Average CPU steal: 94.17%
CPU 0 steal: 95.56%
CPU 1 steal: 92.83%
CPU user: 1.95%
CPU system: 0.59%
CPU iowait: 0.59%
CPU idle: 2.18%
Kết quả còn tệ hơn. Các sample vmstat vẫn cho thấy 91–98% steal, với tối đa 15 process runnable đang chờ CPU. Tổ hợp quan trọng nhất là:
user: 1.95%
system: 0.59%
steal: 94.17%
Application của tôi gần như không làm gì nữa, nhưng VM vẫn mất gần như toàn bộ scheduling time. Production load thông thường không còn là lời giải thích hợp lý.
Ngay cả localhost cũng chậm một cách vô lý
Tôi còn test HTTPS qua 127.0.0.1, qua đó loại public DNS, ISP của tôi, khoảng cách địa lý và external network path khỏi phép thử.
Khi còn traffic, 4 trong 10 lần thử HTTPS qua localhost thất bại trong TLS handshake. Những request thành công mất 29,30, 22,77, 12,25, 11,87, 11,12 và 9,40 giây. Một số TLS handshake riêng lẻ đã mất khoảng chín giây.
Sau khi bỏ production traffic, localhost tốt hơn nhưng vẫn không ổn định: 0,061, 0,745, 0,830, 0,873, 1,010, 1,117, 1,121, 2,188 và 3,355 giây. Cùng một local operation có thể mất khoảng 61 ms ở lần này và hơn 3,3 giây ở lần tiếp theo.
Phần còn lại của stack cho thấy hậu quả
Có thời điểm tôi thấy khoảng 450 established connection, 122 orphaned connection, 110 FIN-WAIT-1 và 33 CLOSE-WAIT. Listen queue của backend localhost lên khoảng 14–15, trong khi HTTPS lên khoảng 40.
Nginx ghi HTTP 504 sau 142,857, 138,902, 135,064, 129,819 và 128,657 giây. Các request khác giữ mở khoảng 67–130 giây. Tôi cũng thấy secure-connect timeout khoảng 35–41 giây, database network timeout và TLS operation bị trễ.
Nếu nhìn riêng lẻ, chúng có thể giống các vấn đề khác nhau của Nginx, database, network hoặc backend. Nhưng tăng timeout không tạo ra CPU time mà hypervisor không schedule.
RAM và disk không giải thích được vấn đề
VPS vẫn còn khoảng 1,0–1,1 GiB RAM available, gần như không dùng swap, không có OOM event hay OOM-killer activity. Filesystem mới dùng khoảng 20%, còn khoảng 44 GB trống. I/O wait giữ dưới 1% trong các phép đo CPU quan trọng.
Memory không cạn, disk không đầy và application của tôi không tiêu thụ phần CPU bị thiếu. Metric chi phối vẫn là %steal.
Một KVM VPS khỏe mạnh trông hoàn toàn khác
Tôi chạy cùng kiểu chẩn đoán trên một KVM VPS khác đang thực sự phục vụ traffic bình thường:
Average CPU steal: 0.02%
CPU idle: 87.86%
CPU PSI avg10: 0.29
CPU PSI avg60: 0.63
CPU PSI avg300: 0.49
Load average: 0.47 / 0.33 / 0.14
Mười request HTTPS localhost hoàn tất trong khoảng 37–69 ms. Sau đó trên một production VPS khác thực sự bận, tôi đo được 61,71% user CPU, 5,08% system CPU, 24,09% idle và chỉ 0,13% steal.
Đó là khác biệt mà giờ tôi quan tâm. VPS có thể bận vì software của tôi thực sự dùng processor. Điều đó hoàn toàn khác với guest dành hơn 90% CPU time đo được để chờ hypervisor.
Cuối cùng REGXA xác nhận contention ở tầng hạ tầng
Từ bên trong VM tôi có thể đo guest, nhưng không thể thấy physical host, scheduler configuration, CPU quota hay các VM hàng xóm. REGXA thì có thể.
Support cuối cùng nói VPS được đặt trên shared CPU infrastructure, CPU resource được chia sẻ giữa nhiều virtual machine và performance có thể thay đổi theo load trên physical node. Họ cũng nói infrastructure ở Frankfurt đang có demand đặc biệt cao và trực tiếp quy CPU steal cao của tôi cho resource contention on the underlying infrastructure.
Họ còn nói không thể thay đổi CPU quota hoặc scheduling policy hay cấp thêm dedicated CPU resource cho shared VPS này trên infrastructure hiện tại. Giải pháp kỹ thuật được đề xuất là chuyển VPS sang location có utilization thấp hơn.
Điều đó khó hòa hợp với ngôn ngữ tôi từng thấy về dedicated CPU cores và guaranteed resources. Tôi không thấy exact host configuration nên không thể kết luận cơ chế trực tiếp là CPU overcommitment, quota, scheduler weighting, throttling hay kết hợp nhiều thứ. Tôi cũng không thể chứng minh ý định. Không cần phải làm vậy: Linux liên tục cho thấy 92–94% steal và chính REGXA đã liên hệ mức steal cao này với contention trên shared infrastructure.
Việc lấy lại tiền cũng cần thêm một vòng kiên trì
Khi vấn đề infrastructure đã rõ, tôi không muốn tiếp tục chuyển VPS và thử các node khác. Tôi muốn hủy service và lấy lại tiền.
Ban đầu tôi chỉ được đề nghị hoàn một phần, và khoản refund được đề xuất sẽ vào REGXA account balance thay vì quay lại thẻ đã dùng để thanh toán. Với tôi, provider credit không tương đương refund khi tôi đang muốn rời khỏi service.
Vì vậy tôi tiếp tục trả lời và yêu cầu hoàn 100% payment về original payment method. Cuối cùng REGXA đồng ý và hoàn toàn bộ số tiền về phương thức thanh toán ban đầu, mô tả full refund này là một exception.
Tôi ghi nhận việc cuối cùng họ đã trả lại toàn bộ tiền. Nhưng việc vẫn phải tiếp tục gây sức ép cho phần giải quyết tài chính sau khi support đã công nhận infrastructure contention cũng là một phần trong trải nghiệm của tôi.
Bài học tôi giữ lại sau sự cố này
Sai lầm dễ nhất là tiếp tục optimize application. Tôi có thể thay đổi Nginx, tăng timeout, giảm concurrency, thêm retry, điều tra MongoDB hoặc viết lại backend. Một số symptom có thể thay đổi. Nhưng không điều gì trả lời câu hỏi quan trọng: tại sao CPU steal lại trên 90%?
Bây giờ tôi không dừng lại sau khi xác nhận SSH hoạt động, Nginx start và health endpoint trả 200. Trên VPS mới tôi cũng kiểm tra %user, %system, %iowait, %idle, %steal, CPU PSI, run queue và localhost latency.
Khi thấy điều gì đáng ngờ, tôi loại workload và đo lại. Trong trường hợp này, đó là phép thử cho kết quả rõ ràng nhất của toàn bộ sự cố:
CPU user: 1.95%
CPU system: 0.59%
CPU steal: 94.17%
Tôi không khẳng định mọi VPS REGXA đều như vậy. Tôi test một VPS và ghi lại điều xảy ra với chính máy đó. Nhưng trên VPS này, bằng chứng rõ ràng một cách bất thường: application gần như không dùng CPU, trong khi Linux cho thấy phần lớn virtual CPU time bị mất khi chờ hypervisor scheduling. Sau đó REGXA cũng quy chính hành vi này cho resource contention trên shared infrastructure của họ.
Đó là lý do tôi ghi lại trải nghiệm này. Không phải như một điểm số hay khuyến nghị, mà đơn giản là một ngày trong công việc của developer — và một metric mà tôi sẽ không bao giờ bỏ qua trên VPS nữa.