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

คู่มือเกมแลค › L8 ซ็อกเก็ตและโปรโตคอล

การกระจายของ SO_REUSEPORT ไม่สมดุล SO_REUSEPORT imbalance, stuck worker

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

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

เมื่อหลายโปรเซสแบ่งกันรับพอร์ตเดียวกัน เคอร์เนลจะกำหนดโปรเซสที่รับแต่ละการเชื่อมต่อด้วย hash ของที่อยู่ และไม่เปลี่ยนอีก ถ้าโปรเซสตัวใดหยุด เฉพาะคนที่ถูกจัดให้โปรเซสนั้นจะต้องรอ

ทำไม เกตเวย์หรือเซิร์ฟเวอร์ล็อกอินรันหลายโปรเซสด้วย SO_REUSEPORT → ผลคือ แม้โปรเซสหนึ่งหยุดเพราะ GC หรือโหลดเกิน การเชื่อมต่อใหม่และแพ็กเก็ต UDP ที่ถูกจัดให้โปรเซสนั้นก็ไม่ย้ายไปโปรเซสอื่น → บนหน้าจอ บางคนเท่านั้นที่เข้าเกมไม่ได้หรือค้าง ตอนรีสตาร์ตที่จำนวนโปรเซสเปลี่ยน เซสชัน UDP บางส่วนจะหลุด

อาการ
เข้าเกมไม่ได้/โหลดไม่จบ, ค้าง, หลุด
ปัจจัย
การหยุดชะงัก, แพ็กเก็ตหาย
ใครเจอ
เราคนเดียว, ทั้งเซิร์ฟเวอร์
เกิดเมื่อไร
หลังล็อกอิน/หลังปิดปรับปรุง, สุ่มเป็นครั้งคราว
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
งานฝั่งทีมพัฒนาเกม
อย่าให้เธรดรับหยุดเด็ดขาด, ทำขั้นตอนส่งต่อเซสชันตอนรีสตาร์ต
งานฝั่งทีมอินฟรา
มอนิเตอร์คิวรอเชื่อมต่อของแต่ละโปรเซส (Recv-Q ของ ss), ถ้า deploy แล้วจำนวนโปรเซสเปลี่ยน ให้ทำตามขั้นตอนส่งต่อเซสชัน
บนกราฟ
สูงเฉพาะบางกลุ่ม · คิวรอเชื่อมต่อ (Recv-Q) ของแต่ละซ็อกเก็ตที่ listen
จุดที่ต้องดู
Recv-Q (จำนวนการเชื่อมต่อที่รอ accept) และโปรเซสเจ้าของของแต่ละซ็อกเก็ตที่ listen บนพอร์ตเดียวกันจาก ss -ltnp และเทียบ throughput ของแต่ละโปรเซส
สัญญาณว่าใช่
ในซ็อกเก็ตหลายตัวบนพอร์ตเดียวกัน มีตัวเดียวที่ Recv-Q สะสมเรื่อย ๆ และโปรเซสนั้นหยุดอยู่หรือ throughput ใกล้ 0
สัญญาณว่าไม่ใช่
Recv-Q ของทุกซ็อกเก็ตสะสมเท่า ๆ กัน: น่าจะเป็นโหลดเกินทั้งระบบ (“คิวรอเชื่อมต่อ (backlog) ล้น”)
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)

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

  1. socket(7) — Linux manual page Linux man-pages
    SO_REUSEPORT ให้ซ็อกเก็ตหลายตัว bind ที่อยู่เดียวกันและแบ่งกันรับการเชื่อมต่อ TCP และแพ็กเก็ต UDP
  2. net/core/sock_reuseport.c (Linux v6.12) Linux kernel
    ถ้าไม่มีโปรแกรม BPF จะนำค่า hash ของแพ็กเก็ตมาแบ่งตามจำนวนซ็อกเก็ตในกลุ่มเพื่อเลือกซ็อกเก็ตที่รับ
  3. Why does one NGINX worker take all the load? Cloudflare
    SO_REUSEPORT แบ่งคิวให้ worker แต่ละตัวด้วย hash แบบง่าย ถ้า worker ตัวหนึ่งติดขัด การเชื่อมต่อทั้งหมดที่กองอยู่ในคิวนั้นจะหยุดหมด
  4. net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
    ค่า Recv-Q และ Send-Q ของ ss: ซ็อกเก็ตที่ listen อยู่คือจำนวนการเชื่อมต่อที่รอ accept และขีดจำกัด backlog, ซ็อกเก็ตที่เชื่อมต่อแล้วคือไบต์ที่แอปยังไม่ได้อ่าน และไบต์ที่ส่งไปแล้วแต่ยังไม่ได้รับ ACK

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

ชั้นเดียวกัน: L8 ซ็อกเก็ตและโปรโตคอล

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

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