ระบบ module proxy ของภาษาโปรแกรม Go ได้สร้างปัญหาร้ายแรงให้กับผู้ดูแล repository ด้วยการดาวน์โหลด codebase ทั้งหมดซ้ำแล้วซ้ำเล่า แทนที่จะตรวจสอบการอัปเดตอย่างมีประสิทธิภาพ ปัญหานี้ดำเนินต่อมาเป็นเวลาหลายปี สร้างสิ่งที่เรียกว่าปัญหา thundering herd ที่สามารถทำให้ upstream server ล้นหลาม
ปัญหาการ Clone ที่ไม่มีประสิทธิภาพ
ระบบ Go proxy ทำการ clone repository ทั้งหมดตั้งแต่เริ่มต้นทุกครั้งที่ตรวจสอบการอัปเดต แทนที่จะใช้วิธีการที่มีประสิทธิภาพมากกว่า เช่น คำสั่ง hg pull
ของ Mercurial สิ่งนี้กลายเป็นปัญหาโดยเฉพาะสำหรับ repository ที่มีไฟล์ขนาดใหญ่ - โปรเจกต์บางตัวเช่น wasmtime-go มี prebuilt archive หลายกิกะไบต์ที่ถูกดาวน์โหลดซ้ำแล้วซ้ำเล่า นักพัฒนาคนหนึ่งถูกบังคับให้ใช้ rate limit ที่อนุญาตให้ clone ได้เพียงครั้งเดียวต่อ repository ทุก 24 ชั่วโมง หลังจากนั้น proxy จะได้รับ error code 429
Mercurial (hg): ระบบควบคุมเวอร์ชันแบบกระจายที่คล้ายกับ Git ซึ่งเคยถูกใช้โดยโปรเจกต์ Go ในอดีตก่อนที่จะย้ายไปใช้ Git
ผลกระทบทางเทคนิค:
- คำขอ clone หลายรายการพร้อมกันจากเครื่อง proxy ที่แตกต่างกัน
- การดาวน์โหลด repository แบบสมบูรณ์แทนการอัปเดตแบบเพิ่มเติม
- ความล่าช้า 14 วินาทีก่อนที่ thundering herd จะเริ่มทำงาน
- ส่งผลกระทบต่อ repository ที่มีไฟล์ binary ขนาดใหญ่ (หลายกิกะไบต์ใน wasmtime-go )
เครื่องหลายเครื่องแข่งขันเพื่อข้อมูลเดียวกัน
เมื่อ proxy ตรวจพบเวอร์ชันใหม่ แทนที่จะแชร์เนื้อหาที่ดาวน์โหลดแล้วภายใน เครื่องหลายเครื่องจะพยายาม clone repository เดียวกันพร้อมกัน การวิเคราะห์ server log แสดงให้เห็นว่าภายใน 14 วินาทีหลังจากที่ node หนึ่งค้นพบการอัปเดต เครื่องห้าเครื่องที่แตกต่างกันกำลังดำเนินการ clone request จาก upstream server เดียวกันพร้อมกัน สิ่งนี้สร้างภาระที่ไม่จำเป็นทั้งที่ data center ของ Google ที่เชื่อมต่อได้ดีมีการเชื่อมต่อภายในที่ดีกว่าการเชื่อมต่อภายนอก
ปัญหาที่มีมาสามปี
การอภิปรายในชุมชนเผยให้เห็นว่านี่ไม่ใช่ปัญหาใหม่ SourceHut เคยขู่ว่าจะแบน Go เมื่อสามปีที่แล้วเนื่องจากพฤติกรรมนี้เป็นอย่างแน่นอน แต่ปัญหายังคงอยู่จนถึงทุกวันนี้ สถานการณ์นี้ดูเหมือนจะเกิดจากสิ่งที่บางคนอธิบายว่าเป็น software ที่ถูกทอดทิ้ง - ระบบที่ได้รับแนวทางที่พอใช้ได้แทนที่จะได้รับความสนใจที่เหมาะสมในการเพิ่มประสิทธิภาพ
ไทม์ไลน์ของปัญหา Go Proxy:
- 2022: SourceHut ขู่ว่าจะแบน Go เนื่องจากการโจมตีเซิร์ฟเวอร์อย่างหนัก
- 2025: ปัญหายังคงมีอยู่ด้วยพฤติกรรม thundering herd
- ปัจจุบัน: ได้ใช้ rate limiting แล้ว (1 clone ต่อ repo ต่อ 24 ชั่วโมง)
การตอบสนองของ Google และแนวทางแก้ไขที่เป็นไปได้
ตัวแทนของ Google ยอมรับปัญหา thundering herd และขอโทษสำหรับ traffic ที่มากเกินไป พวกเขาอธิบายว่าแม้จะแก้ไขปัญหาที่คล้ายกันสำหรับ Git repository แล้วด้วยการใช้ reuse flag ที่ตรวจสอบการเปลี่ยนแปลงโดยไม่ต้องดาวน์โหลดทั้งหมด แต่การสนับสนุน Mercurial ยังคงไม่สมบูรณ์ ความท้าทายอยู่ที่การหาวิธีให้ระบบควบคุมเวอร์ชันสามารถจัดหาวิธีการที่ไม่แพงในการแสดงรายการ tag และ branch พร้อมกับ cryptographic checksum โดยไม่ต้อง clone repository ทั้งหมด
สถานการณ์ที่เกิดขึ้นอย่างต่อเนื่องนี้เน้นให้เห็นว่าแม้แต่บริษัทที่มีทรัพยากรมากก็สามารถมองข้ามผลกระทบของระบบของพวกเขาต่อผู้ให้บริการ upstream ที่เล็กกว่า ซึ่งสร้างปัญหาประสิทธิภาพแบบลูกโซ่ทั่วทั้ง ecosystem การพัฒนา
อ้างอิง: what is the go proxy even doing?