กลับไปที่บล็อก
31 สิงหาคม 2569Sergei Solod13 นาทีในการอ่าน

VPS ของ REGXA ที่ผมใช้มี CPU Steal 94% แม้ไม่มีทราฟฟิก

ระหว่างตรวจสอบปัญหาประสิทธิภาพรุนแรงบน KVM VPS ของ REGXA ผมพบ CPU steal 92–94%, request ผ่าน localhost ที่กินเวลาหลายวินาที, queue การเชื่อมต่อที่เพิ่มขึ้น และ HTTP 504 ที่ใช้เวลามากกว่าสองนาที หลังเอา production traffic ออกทั้งหมด CPU steal กลับเพิ่มเป็น 94.17% และภายหลัง REGXA ระบุว่าเกิดจาก resource contention บน shared infrastructure ของตน

REGXAVPSLinuxCPU stealเวอร์ชวลไลเซชัน

ผมไม่ได้เขียนเรื่องนี้เพื่อรีวิว REGXA ในแง่ลบ และไม่ได้พยายามบอกว่าใครควรหรือไม่ควรซื้อ VPS จากที่นี่ นี่เป็นเพียงหนึ่งวันธรรมดาในชีวิตการทำงานของผมในฐานะ developer

ผมย้าย workload ปกติไปยัง KVM VPS ที่มี 2 vCPU, RAM 2 GB และ NVMe 60 GB ทั้ง Nginx และ backend ทำงานอยู่ แต่เครื่องกลับมีอาการเหมือน overload อย่างหนัก request เริ่มสะสม, TLS ช้าลง, connection เปิดค้าง และบาง request ใช้เวลามากกว่าสองนาทีก่อนจบด้วย HTTP 504

ตัวเลข CPU accounting เปลี่ยนทิศทางการวิเคราะห์

ข้อสันนิษฐานแรกของผมตรงไปตรงมา: มีบางอย่างใน VPS กำลังกิน CPU จากนั้นผมจึงรัน 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%

แต่ละ sample แสดง steal ราว 89–98% ซ้ำ ๆ และ CPU pressure ก็สูงมาก:

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

นี่คือ VM ที่มีเพียงสอง vCPU แต่ Linux มี runnable process รอ CPU อยู่ ตัวเลขสำคัญไม่ใช่การใช้ CPU ตามปกติของ application แต่คือ %steal

CPU ใช้งานสูงกับ CPU steal เป็นคนละปัญหา

ถ้า application ของผมใช้ processor จริง ๆ ผมควรเห็นค่า user หรือ system สูง แต่ภาพของ VPS กลับประมาณนี้:

user: 4%
system: 1%
steal: 93%

CPU steal คือช่วงเวลาที่ virtual CPU พร้อมทำงาน แต่ hypervisor ไม่ schedule ให้มันทำงาน ดังนั้นเมื่อผมบอกว่า VPS ถูกดึง CPU time ออกไป ผมหมายถึงในความหมายทางเทคนิคของ virtualization นี้ ผมพิสูจน์ไม่ได้ว่า REGXA ตั้งใจเอา physical core ที่เป็นของผมโดยเฉพาะไปให้ลูกค้าคนอื่น และ guest metric ก็ไม่สามารถใช้สรุปเจตนาได้ สิ่งที่พิสูจน์ได้คือ guest มีงานพร้อมทำซ้ำ ๆ แต่ไม่ได้รับ CPU scheduling time

ผมเอา production traffic ออกทั้งหมด

ยังมีข้อโต้แย้งที่สมเหตุสมผล: workload ของผมเองอาจเป็นสาเหตุ ผมจึงเอาตัวแปรนั้นออก ย้าย workload ที่ใช้งานอยู่ไปที่อื่น หยุด production traffic มายัง VPS นี้ รอให้ queue ว่าง แล้ววัดใหม่

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%

ผลกลับแย่กว่าเดิม sample ของ vmstat ยังคงแสดง steal 91–98% และมี runnable process สูงสุด 15 ตัวรอ CPU สิ่งสำคัญคือชุดตัวเลขนี้:

user: 1.95%
system: 0.59%
steal: 94.17%

application ของผมแทบไม่ได้ทำอะไรแล้ว แต่ VM ยังคงสูญเสีย scheduling time เกือบทั้งหมด production load ตามปกติจึงไม่ใช่คำอธิบายที่น่าเชื่อถืออีกต่อไป

แม้แต่ localhost ก็ช้าอย่างผิดปกติ

ผมทดสอบ HTTPS ผ่าน 127.0.0.1 ด้วย เพื่อเอา public DNS, ISP ของผม, ระยะทางทางภูมิศาสตร์ และเส้นทางเครือข่ายภายนอกออกจากการทดสอบ

ขณะมี traffic การเชื่อมต่อ HTTPS ผ่าน localhost 4 จาก 10 ครั้งล้มเหลวตอน TLS handshake ส่วน request ที่สำเร็จใช้เวลา 29.30, 22.77, 12.25, 11.87, 11.12 และ 9.40 วินาที บาง TLS handshake เพียงอย่างเดียวใช้เวลาราว 9 วินาที

หลังเอา production traffic ออก localhost ดีขึ้นแต่ยังไม่เสถียร: 0.061, 0.745, 0.830, 0.873, 1.010, 1.117, 1.121, 2.188 และ 3.355 วินาที operation เดียวกันในเครื่องเดียวกันอาจใช้ราว 61 ms ครั้งหนึ่ง แล้วมากกว่า 3.3 วินาทีในครั้งถัดไป

ส่วนอื่นของ stack แสดงผลกระทบตามมา

ช่วงหนึ่งผมเห็น established connection ราว 450 รายการ, orphaned connection 122 รายการ, FIN-WAIT-1 110 รายการ และ CLOSE-WAIT 33 รายการ listen queue ของ backend บน localhost ขึ้นไปประมาณ 14–15 และ HTTPS ประมาณ 40

Nginx บันทึก HTTP 504 หลัง 142.857, 138.902, 135.064, 129.819 และ 128.657 วินาที request อื่นเปิดค้างอยู่ราว 67–130 วินาที นอกจากนี้ยังมี secure-connect timeout ราว 35–41 วินาที, database network timeout และ TLS ที่ล่าช้า

ถ้ามองแยกกัน อาการเหล่านี้อาจดูเหมือนปัญหาคนละอย่างของ Nginx, database, network หรือ backend แต่การเพิ่ม timeout ไม่ได้สร้าง CPU time ที่ hypervisor ไม่ได้ schedule

RAM และ disk ไม่ได้อธิบายปัญหานี้

VPS ยังมี RAM available ราว 1.0–1.1 GiB, แทบไม่ใช้ swap, ไม่มี OOM event และไม่มี OOM killer filesystem ใช้ไปเพียงประมาณ 20% โดยเหลือราว 44 GB และ I/O wait ต่ำกว่า 1% ระหว่างการวัด CPU ที่สำคัญ

memory ไม่หมด, disk ไม่เต็ม และ application ของผมไม่ได้ใช้ CPU ที่หายไป metric หลักยังคงเป็น %steal

KVM VPS ที่ปกติดูต่างออกไปอย่างสิ้นเชิง

ผมรันการวิเคราะห์แบบเดียวกันบน KVM VPS อีกตัวที่กำลังให้บริการ traffic ปกติอยู่:

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

localhost HTTPS ทั้งสิบ request ใช้เวลาราว 37–69 ms ต่อมาใน production VPS อีกตัวที่ busy จริง ๆ ผมวัดได้ user CPU 61.71%, system CPU 5.08%, idle 24.09% และ steal เพียง 0.13%

นี่คือความแตกต่างที่ผมให้ความสำคัญในตอนนี้ VPS อาจ busy เพราะ software ของผมใช้ processor จริง ๆ ซึ่งต่างจาก guest ที่ใช้เวลามากกว่า 90% ของ CPU time ที่วัดได้ไปกับการรอ hypervisor

ท้ายที่สุด REGXA ยืนยัน infrastructure contention

จากภายใน VM ผมวัด guest ได้ แต่ไม่เห็น physical host, scheduler configuration, CPU quota หรือ VM ข้างเคียง REGXA มองเห็นข้อมูลเหล่านั้นได้

สุดท้าย support แจ้งว่า VPS อยู่บน shared CPU infrastructure, resource ของ CPU ถูกแชร์ระหว่างหลาย virtual machine และ performance อาจเปลี่ยนไปตาม load ของ physical node พวกเขายังบอกว่า infrastructure ที่ Frankfurt มี demand สูงเป็นพิเศษ และระบุชัดว่า CPU steal ที่สูงของผมเกิดจาก resource contention on the underlying infrastructure

พวกเขายังบอกว่าไม่สามารถเปลี่ยน CPU quota หรือ scheduling policy หรือเพิ่ม dedicated CPU resource ให้ shared VPS นี้บน infrastructure ปัจจุบันได้ ทางแก้ทางเทคนิคที่เสนอคือย้าย VPS ไป location ที่ utilization ต่ำกว่า

คำอธิบายนี้ยากจะสอดคล้องกับคำที่ผมเคยเห็นเกี่ยวกับ dedicated CPU cores และ guaranteed resources ผมมองไม่เห็น exact host configuration จึงบอกไม่ได้ว่ากลไกโดยตรงคือ CPU overcommitment, quota, scheduler weighting, throttling หรือหลายอย่างร่วมกัน ผมพิสูจน์ intent ไม่ได้เช่นกัน และไม่จำเป็นต้องทำ เพราะ Linux แสดง steal 92–94% ต่อเนื่อง และ REGXA เองเชื่อมโยงค่าที่สูงนี้กับ contention บน shared infrastructure

การขอ refund ก็ต้องตามต่ออีกหลายรอบ

เมื่อปัญหาที่ infrastructure ชัดเจนแล้ว ผมไม่อยากย้าย VPS ไปมาเพื่อทดสอบ node อื่นต่อ ผมต้องการยกเลิก service และรับเงินคืน

ตอนแรกผมได้รับข้อเสนอคืนเงินเพียงบางส่วน และ refund ที่เสนอจะเข้ายอด balance ของบัญชี REGXA ไม่ใช่กลับไปยังบัตรที่ใช้จ่าย สำหรับผม provider credit ไม่เท่ากับ refund ถ้าผมกำลังจะออกจาก service

ผมจึงตอบกลับต่อและขอให้คืน 100% ของยอดชำระไปยัง original payment method สุดท้าย REGXA ยอมและคืนเงินเต็มจำนวนกลับไปยังวิธีชำระเงินเดิม โดยระบุว่า full refund นี้เป็น exception

ผมให้เครดิตว่าท้ายที่สุดพวกเขาคืนเงินทั้งหมด แต่การที่ผมยังต้องผลักดันเรื่องการเงินต่อหลังจาก support ยอมรับ infrastructure contention แล้ว ก็เป็นส่วนหนึ่งของประสบการณ์นี้เช่นกัน

สิ่งที่ผมเรียนรู้จากเหตุการณ์นี้

ข้อผิดพลาดที่ง่ายที่สุดคือการ optimize application ต่อไป ผมอาจเปลี่ยน Nginx, เพิ่ม timeout, ลด concurrency, เพิ่ม retry, ตรวจ MongoDB หรือเขียน backend ใหม่ บางอย่างอาจเปลี่ยนอาการได้ แต่ไม่มีอะไรตอบคำถามสำคัญว่าเหตุใด CPU steal จึงสูงกว่า 90%

ตอนนี้ผมไม่หยุดแค่ตรวจว่า SSH ใช้งานได้, Nginx start ได้ และ health endpoint ตอบ 200 บน VPS ใหม่ผมยังดู %user, %system, %iowait, %idle, %steal, CPU PSI, run queue และ localhost latency

และถ้ามีอะไรผิดปกติ ผมจะเอา workload ออกแล้ววัดใหม่ ในกรณีนี้ นั่นคือผลลัพธ์ที่ชัดที่สุดของเหตุการณ์ทั้งหมด:

CPU user: 1.95%
CPU system: 0.59%
CPU steal: 94.17%

ผมไม่ได้บอกว่า REGXA VPS ทุกตัวเป็นแบบนี้ ผมทดสอบ VPS หนึ่งตัวและบันทึกสิ่งที่เกิดขึ้นกับเครื่องนั้น แต่บน VPS ตัวนี้หลักฐานชัดเจนผิดปกติ application ของผมแทบไม่ได้ใช้ CPU แต่ Linux แสดงว่า virtual CPU time ส่วนใหญ่หายไปกับการรอ scheduling จาก hypervisor ต่อมา REGXA ก็เชื่อมโยงพฤติกรรมเดียวกันนี้กับ resource contention บน shared infrastructure ของตน

นี่คือเหตุผลที่ผมบันทึกเรื่องนี้ ไม่ใช่เพื่อให้คะแนนหรือแนะนำ แต่เป็นเพียงหนึ่งวันในชีวิตของ developer และเป็น metric หนึ่งที่ผมจะไม่มองข้ามอีกบน VPS