한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › L9 โปรเซสเกมฝั่งเซิร์ฟเวอร์

thread pool หมด Thread pool starvation

ID สาเหตุ sp-threadpool · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

ถ้า worker thread ที่ประมวลผลงานติดอยู่กับงานช้าทั้งหมด คำขอใหม่จะต้องรอไปเรื่อย ๆ อย่างไม่มีกำหนด

ทำไม worker thread ติดรอการตอบกลับจาก API ภายนอกหรือ DB → ผลคือ ไม่มีเธรดว่างรับคำขอใหม่ → บนหน้าจอ บางฟีเจอร์ เช่น ล็อกอินหรือร้านค้า โหลดไม่จบ

อาการ
เข้าเกมไม่ได้/โหลดไม่จบ, อินพุตดีเลย์, ค้าง
ปัจจัย
การหยุดชะงัก
ใครเจอ
เฉพาะบางฟีเจอร์, ทั้งเซิร์ฟเวอร์
เกิดเมื่อไร
ตอนคนแห่มารวมกัน, หลังล็อกอิน/หลังปิดปรับปรุง
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
งานฝั่งทีมพัฒนาเกม
ตั้งไทม์เอาต์ให้การเรียกที่ช้า, แยก thread pool ตามฟีเจอร์, เปลี่ยนเป็นแบบ asynchronous
บนกราฟ
ชนเพดานแล้วแบนราบ · จำนวนเธรดและความยาวคิวของ thread pool, เวลาประมวลผลคำขอ
จุดที่ต้องดู
สำหรับ .NET ดูจำนวนเธรดและความยาวคิวของ thread pool ใน dotnet-counters monitor (.NET 9 ขึ้นไปคือ dotnet.thread_pool.thread.count และ dotnet.thread_pool.queue.length, 8 ลงไปคือ ThreadPool Thread Count และ ThreadPool Queue Length) และดูว่า worker thread รออยู่ที่ไหนด้วย dotnet-stack สำหรับ JVM และเซิร์ฟเวอร์ native ดูแบบเดียวกันจาก thread dump
สัญญาณว่าใช่
อัตราการใช้ CPU ต่ำกว่า 100% มาก แต่จำนวนเธรดค่อย ๆ เพิ่มขึ้นเรื่อย ๆ หรือติดเพดาน คิวสะสม และ worker ส่วนใหญ่รอการตอบกลับจากการเรียกภายนอกตัวเดียวกัน (DB, HTTP)
สัญญาณว่าไม่ใช่
คิวว่างแต่ยังช้า: ปลายทางที่เรียกช้าเอง น่าจะเป็นความล้มเหลวแบบลูกโซ่หรือการพึ่งพาเซอร์วิสภายนอก
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
รายละเอียดเพิ่มเติม
ถ้าการรับแพ็กเก็ตกับลอจิกเกมใช้ worker thread pool เดียวกัน ทันทีที่งานช้าไม่กี่งานถือครอง worker ทั้งหมด การประมวลผลแพ็กเก็ตของทั้งเซิร์ฟเวอร์จะหยุด
กรณีจริง
Riot Games 2021: League of Legends EUW ขัดข้อง 5 ชั่วโมง: DB เสริมตัวเดียวทำให้ทั้งเซิร์ฟเวอร์หยุด

แหล่งอ้างอิง

  1. Debug ThreadPool Starvation Microsoft
    เมื่อ pool ไม่มีเธรดเหลือและงานใหม่ต้องรอ การตอบสนองจะช้าลง ต้นเหตุคือโค้ดแบบ blocking ที่ถือครองเธรด ใน dotnet-counters ถ้า CPU ต่ำกว่า 100% มากแต่ dotnet.thread_pool.thread.count ค่อย ๆ เพิ่มเรื่อย ๆ คือสัญญาณว่าหมด (dotnet.thread_pool.queue.length มักสูงด้วย), ดูจุดที่เธรดรอด้วย dotnet-stack
  2. Avoiding insurmountable queue backlogs AWS
    จำนวนงานพร้อมกัน = อัตราการเข้ามา × ความหน่วง (กฎของ Little) ที่ 100 คำขอต่อวินาที ถ้าความหน่วงเพิ่มจาก 100 ms เป็น 10 วินาที เธรด 10 ตัวจะกลายเป็น 1,000 ตัวจน pool หมด
  3. Bulkhead Pattern Microsoft Azure
    ถ้าแยก connection pool และ thread pool ไว้ต่อปลายทางที่เรียก ความขัดข้องของปลายทางหนึ่งจะบล็อกแค่ pool ของมันเอง
  4. .NET runtime metrics .NET
    dotnet.thread_pool.thread.count (จำนวนเธรดของ thread pool) และ dotnet.thread_pool.queue.length (จำนวนงานที่รออยู่) มีตั้งแต่ .NET 9
  5. Well-known EventCounters in .NET Microsoft
    ThreadPool Thread Count (threadpool-thread-count) และ ThreadPool Queue Length (threadpool-queue-length) ของ .NET 8 ลงไป

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: L9 โปรเซสเกมฝั่งเซิร์ฟเวอร์

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (เข้าเกมไม่ได้/โหลดไม่จบ)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง