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

คู่มือเกมแลค › 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 สั้นลง

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

  1. IP Sysctl Linux kernel
    ip_local_port_range ค่าเริ่มต้น 32768–60999, tcp_tw_reuse, tcp_fin_timeout คือระยะเวลาที่คงสถานะ FIN_WAIT_2
  2. include/net/tcp.h (Linux v6.12) Linux kernel
    TCP_TIMEWAIT_LEN (60*HZ): TIME_WAIT ประมาณ 60 วินาทีเป็นค่าคงที่ของเคอร์เนล
  3. TCP/IP port exhaustion troubleshooting Microsoft
    ช่วง dynamic port เริ่มต้นของ Windows คือ 49152–65535 และการเชื่อมต่อที่ปิดแล้วจะถือพอร์ตไว้ในสถานะ TIME_WAIT 4 นาทีโดยค่าเริ่มต้น
  4. ss(8) — Linux manual page iproute2
    ใช้ตัวกรองสถานะ state time-wait เพื่อดูเฉพาะซ็อกเก็ต TIME_WAIT
  5. connect(2) — Linux manual page Linux man-pages
    EADDRNOTAVAIL: เปิดการเชื่อมต่อไม่ได้เพราะพอร์ตทั้งหมดในช่วง ephemeral port ถูกใช้อยู่

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

ชั้นเดียวกัน: L7 OS ของเซิร์ฟเวอร์ (เคอร์เนล)

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

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