คู่มือเกมแลค › L9 โปรเซสเกมฝั่งเซิร์ฟเวอร์
เดดล็อก Deadlock
ID สาเหตุ sp-deadlock · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าสองเธรดต่างรอล็อกที่อีกฝ่ายถืออยู่ ทั้งคู่จะหยุดไปตลอดกาล
ทำไม เธรด A ถือล็อก 1 แล้วรอล็อก 2 ส่วน B ถือล็อก 2 แล้วรอล็อก 1 → ผลคือ ทั้งคู่หยุดไปตลอดกาล และเธรดที่เกี่ยวข้องก็หยุดตามกันเป็นทอด ๆ → บนหน้าจอ ทั้งเซิร์ฟเวอร์ค้าง และเมื่อ watchdog รีสตาร์ต ทุกคนก็หลุด
- อาการ
- ค้าง, หลุด
- ปัจจัย
- การหยุดชะงัก
- ใครเจอ
- ทั้งเซิร์ฟเวอร์, เฉพาะบางฟีเจอร์
- เกิดเมื่อไร
- สุ่มเป็นครั้งคราว, ตอนคนแห่มารวมกัน
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- กำหนดกฎลำดับการถือล็อก, ใช้ล็อกที่มีไทม์เอาต์, มี watchdog และเก็บ thread dump ตอนที่โปรเซสหยุด
- บนกราฟ
- การเชื่อมต่อหลุดพร้อมกัน · จำนวนการเชื่อมต่อ, ปริมาณที่เซิร์ฟเวอร์ส่งออก
- จุดที่ต้องดู
- call stack ของทุกเธรดที่เก็บไว้ระหว่างที่หยุด JVM ใช้ jstack (หาเดดล็อกและแสดงให้อัตโนมัติ) .NET ใช้ dotnet-stack เซิร์ฟเวอร์ native ใช้ thread apply all bt ของ gdb หรือใช้ gcore เก็บ core file ไว้ก่อน แล้วรีสตาร์ตและวิเคราะห์ภายหลัง
- สัญญาณว่าใช่
- มีเธรดตั้งแต่สองตัวขึ้นไปหยุดอยู่ใน stack ที่รอล็อกที่อีกฝ่ายถือ และระหว่างนั้นอัตราการใช้ CPU ของโปรเซสใกล้ 0
- สัญญาณว่าไม่ใช่
- ระหว่างที่หยุดมีเธรดหนึ่งวิ่งอยู่ที่ CPU 100%: ลูปไม่รู้จบ ถ้าเธรดรอการตอบกลับจาก DB หรือภายนอก: น่าจะเป็น synchronous call หรือ thread pool หมด
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
แหล่งอ้างอิง
- Runtime locking correctness validator Linux kernel
ถ้าถือล็อกสองตัวในลำดับสลับกัน จะเกิดการรอวนเป็นเดดล็อก (lock inversion deadlock), เคอร์เนล Linux ตรวจลำดับการถือล็อกและเตือนล่วงหน้า - Liveness, Readiness, and Startup Probes Kubernetes
liveness probe จับสถานะเดดล็อกที่แอปยังรันอยู่แต่ทำงานต่อไม่ได้ แล้วรีสตาร์ตคอนเทนเนอร์ - Diagnostic Tools (Java SE 21 Troubleshooting Guide) Oracle
jstack พิมพ์ stack ของทุกเธรดใน JVM ที่กำลังรัน และหาเดดล็อกแล้วแสดงด้วย (Found one Java-level deadlock) - dotnet-stack diagnostic tool - .NET CLI Microsoft
เก็บและพิมพ์ managed stack ของทุกเธรดในโปรเซส .NET - Threads (Debugging with GDB) GNU Project
thread apply all รันคำสั่งเดียวกัน (bt: พิมพ์ call stack) กับทุกเธรด - gcore(1) — Linux manual page gdb
สร้าง core file ของโปรแกรมที่กำลังรัน และโปรแกรมยังรันต่อไปตามเดิมหลังสร้างเสร็จ
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L9 โปรเซสเกมฝั่งเซิร์ฟเวอร์
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง