คู่มือเกมแลค › L7 OS ของเซิร์ฟเวอร์ (เคอร์เนล)
ขีดจำกัด file descriptor File descriptor limit (ulimit)
ID สาเหตุ so-fd · ผู้รับผิดชอบหลัก อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ทุกการเชื่อมต่อต้องใช้ file descriptor (fd คือหมายเลขที่ OS กำหนดให้ไฟล์หรือซ็อกเก็ตที่เปิดอยู่) แต่จำนวน fd ที่หนึ่งโปรเซสเปิดได้มีจำกัด
ทำไม จำนวนผู้เล่นออนไลน์พร้อมกันแตะขีดจำกัด file descriptor ของโปรเซส → ผลคือ เซิร์ฟเวอร์รับการเชื่อมต่อใหม่ไม่ได้ (Too many open files) การเปิดไฟล์ log และการเชื่อมต่อ DB ก็ล้มเหลวไปด้วย → บนหน้าจอ พอถึงจำนวนคนค่าหนึ่งพอดีก็ไม่มีใครเข้าได้อีก: เข้าเกมไม่ได้/โหลดไม่จบ
- อาการ
- เข้าเกมไม่ได้/โหลดไม่จบ
- ปัจจัย
- แพ็กเก็ตหาย
- ใครเจอ
- ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- หลังล็อกอิน/หลังปิดปรับปรุง, ตอนคนแห่มารวมกัน
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา) · ร่วมกับ พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม)
- งานฝั่งทีมพัฒนาเกม
- ปิดซ็อกเก็ตให้แน่นอนเมื่อจบการเชื่อมต่อ (กัน fd รั่ว), ถ้า accept ล้มเหลวด้วย EMFILE (fd ไม่พอ) ให้หยุดรับการเชื่อมต่อชั่วครู่ หรือใช้ fd สำรองที่กันไว้รับแล้วปิดทันที (จะได้ไม่เสีย CPU ไปกับการจัดการแจ้งเตือนการเชื่อมต่อเดิมซ้ำ ๆ)
- งานฝั่งทีมอินฟรา
- ตรวจ ulimit และการตั้งค่าเซอร์วิส (LimitNOFILE ของ systemd), ตั้ง alert เมื่อใกล้ขีดจำกัด
- ตัวเลขที่ควรรู้
- บน Linux ถ้าไม่ได้ตั้งค่าเซอร์วิสแยกไว้ ขีดจำกัดยังเป็น 1,024 อยู่บ่อย ๆ เซิร์ฟเวอร์เกมมักเพิ่มเป็นหลายหมื่นถึงหลายแสน ส่วน Windows ไม่มีขีดจำกัดเริ่มต้นที่ต่ำแบบนี้
- บนกราฟ
- ชนเพดานแล้วแบนราบ · จำนวน fd ที่โปรเซสเปิดอยู่, จำนวนผู้เล่นออนไลน์พร้อมกัน
- จุดที่ต้องดู
- fd-nr (จำนวน file descriptor ที่เปิดอยู่) ของโปรเซสเซิร์ฟเวอร์เกมจาก pidstat -v, ขีดจำกัดจำนวนไฟล์ที่เปิดได้จาก /proc/PID/limits และ accept ที่ล้มเหลว (EMFILE, Too many open files) ใน log ของเซิร์ฟเวอร์
- สัญญาณว่าใช่
- จำนวน fd แบนราบที่ค่าขีดจำกัด และตั้งแต่ตอนนั้น accept ล้มเหลวด้วย EMFILE
- สัญญาณว่าไม่ใช่
- จำนวน fd ยังห่างจากขีดจำกัดมาก: ไม่ใช่สาเหตุนี้ ถ้าคำขอเชื่อมต่อถูกทิ้งในเคอร์เนล ให้ดู “คิวรอเชื่อมต่อ (backlog) ล้น” ถ้าเกี่ยวกับ connection tracking ให้ดู “ตาราง conntrack ของเซิร์ฟเวอร์เต็ม”
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- การเชื่อมต่อที่รับไม่ได้จะยังรออยู่ในคิวรอเชื่อมต่อ (backlog) ของเคอร์เนล ขึ้นอยู่กับโค้ดเซิร์ฟเวอร์ บางครั้งจะได้รับแจ้ง “มีการเชื่อมต่อใหม่” ซ้ำไปเรื่อย ๆ จนเปลือง CPU
แหล่งอ้างอิง
- systemd-system.conf(5) — Linux manual page systemd
ค่าเริ่มต้นของ DefaultLimitNOFILE สำหรับเซอร์วิสคือ 1024:524288 (soft limit 1,024) - accept(2) — Linux manual page Linux man-pages
เมื่อโปรเซสแตะขีดจำกัด fd แล้ว accept จะล้มเหลวด้วย EMFILE - Maximum Number of Sockets Supported Microsoft
Winsock ของ Windows จำกัดจำนวนซ็อกเก็ตด้วยหน่วยความจำที่ใช้ได้เท่านั้น - pidstat(1) — Linux manual page sysstat
fd-nr ของ -v: จำนวน file descriptor ที่โปรเซสเปิดอยู่ - proc_pid_limits(5) — Linux manual page Linux man-pages
/proc/PID/limits แสดงค่า soft และ hard ของขีดจำกัดทรัพยากรแต่ละรายการของโปรเซส
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L7 OS ของเซิร์ฟเวอร์ (เคอร์เนล)
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (เข้าเกมไม่ได้/โหลดไม่จบ)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง