คู่มือเกมแลค › L7 OS ของเซิร์ฟเวอร์ (เคอร์เนล)
ephemeral port หมดในการเชื่อมต่อระหว่างเซิร์ฟเวอร์ Ephemeral port exhaustion (TIME_WAIT)
ID สาเหตุ so-ports · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าเซิร์ฟเวอร์เกมเปิดและปิดการเชื่อมต่อสั้น ๆ ไปยัง DB หรือเซิร์ฟเวอร์อื่นบ่อย ๆ การเชื่อมต่อที่ปิดแล้วจะยังถือครองพอร์ตอยู่สักพัก จนเปิดการเชื่อมต่อใหม่ไม่ได้
ทำไม เปิดและปิดการเชื่อมต่อใหม่ทุกคำขอ → ผลคือ ฝั่งที่ปิดก่อนจะถือครองพอร์ตไว้ประมาณ 60 วินาทีบน Linux (TIME_WAIT) จนพอร์ตที่ใช้ได้หมด → บนหน้าจอ คำขอภายในล้มเหลว: บันทึกข้อมูลไม่สำเร็จ, ฟีเจอร์ทำงานผิดพลาด
อาการ กดไม่ติด/โรลแบ็ค , เข้าเกมไม่ได้/โหลดไม่จบ
ปัจจัย แพ็กเก็ตหาย
ใครเจอ ทั้งเซิร์ฟเวอร์, เฉพาะบางฟีเจอร์
เกิดเมื่อไร ตอนคนแห่มารวมกัน
ผู้รับผิดชอบ ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
งานฝั่งทีมพัฒนาเกม ใช้การเชื่อมต่อซ้ำ (connection pool), เลิกเปิดและปิดการเชื่อมต่อใหม่ทุกคำขอ
งานฝั่งทีมอินฟรา ขยายช่วงพอร์ต (ip_local_port_range), พิจารณาใช้ TIME_WAIT ซ้ำสำหรับการเชื่อมต่อขาออก (tcp_tw_reuse ของ Linux), มอนิเตอร์จำนวน TIME_WAIT
ตัวเลขที่ควรรู้ ช่วงพอร์ตเริ่มต้นของ Linux (32768–60999) มีประมาณ 28,000 พอร์ต ถ้าเปิดการเชื่อมต่อใหม่ไปยังปลายทางเดียวกันเกิน 470 ครั้งใน 1 วินาที พอร์ตจะหมด Windows มีพอร์ตเริ่มต้นประมาณ 16,000 พอร์ต (49152–65535) และ TIME_WAIT ยาวกว่า จึงหมดเร็วกว่า
บนกราฟ ชนเพดานแล้วแบนราบ · จำนวนซ็อกเก็ต TIME_WAIT, จำนวนการเชื่อมต่อภายในที่ล้มเหลว
จุดที่ต้องดู นับซ็อกเก็ต TIME_WAIT แยกตามปลายทางด้วย ss -tan state time-wait และหา connect ที่ล้มเหลว (EADDRNOTAVAIL) ใน log ของเซิร์ฟเวอร์เกม สัญญาณว่าใช่ TIME_WAIT ไปยังปลายทางเดียวกัน (เช่น DB) แบนราบใกล้ขนาดช่วง ephemeral port (ค่าเริ่มต้นประมาณ 28,000) และ connect ล้มเหลวด้วย EADDRNOTAVAIL สัญญาณว่าไม่ใช่ TIME_WAIT น้อย แต่เฉพาะการเชื่อมต่อออกไปภายนอกที่ล้มเหลว: ให้ดู “ขีดจำกัดการเชื่อมต่อ/พอร์ตของ NAT gateway บนคลาวด์” วิธีตรวจ ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
รายละเอียดเพิ่มเติม TIME_WAIT 60 วินาทีของ Linux เป็นค่าที่ฝังตายตัวในเคอร์เนล การลด tcp_fin_timeout ซึ่งชื่อคล้ายกันไม่ได้ทำให้ TIME_WAIT สั้นลง
แหล่งอ้างอิง IP Sysctl Linux kernel ip_local_port_range ค่าเริ่มต้น 32768–60999, tcp_tw_reuse, tcp_fin_timeout คือระยะเวลาที่คงสถานะ FIN_WAIT_2 include/net/tcp.h (Linux v6.12) Linux kernel TCP_TIMEWAIT_LEN (60*HZ): TIME_WAIT ประมาณ 60 วินาทีเป็นค่าคงที่ของเคอร์เนล TCP/IP port exhaustion troubleshooting Microsoft ช่วง dynamic port เริ่มต้นของ Windows คือ 49152–65535 และการเชื่อมต่อที่ปิดแล้วจะถือพอร์ตไว้ในสถานะ TIME_WAIT 4 นาทีโดยค่าเริ่มต้น ss(8) — Linux manual page iproute2 ใช้ตัวกรองสถานะ state time-wait เพื่อดูเฉพาะซ็อกเก็ต TIME_WAIT connect(2) — Linux manual page Linux man-pages EADDRNOTAVAIL: เปิดการเชื่อมต่อไม่ได้เพราะพอร์ตทั้งหมดในช่วง ephemeral port ถูกใช้อยู่
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L7 OS ของเซิร์ฟเวอร์ (เคอร์เนล)
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (กดไม่ติด/โรลแบ็ค)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง