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