35 คะแนน โดย GN⁺ 2024-05-18 | 2 ความคิดเห็น | แชร์ทาง WhatsApp

ทำไมจึงต้องมี Rate Limit (การจำกัดการใช้งาน)?

  • ในแชต Twitch ที่มีผู้เข้าร่วมจำนวนมาก หากมีสแปมเมอร์เพียงคนเดียวและไม่มีการจำกัดการใช้งาน สแปมเมอร์คนนั้นก็อาจครอบงำบทสนทนาได้
  • การจำกัดการใช้งานช่วยให้ผู้ใช้แต่ละคนมีโอกาสเข้าร่วมได้อย่างเป็นธรรม
  • Rate Limiter (ตัวจำกัดการใช้งาน) ใช้ควบคุมทราฟฟิกของบริการด้วยการบล็อกคำขอที่เกินขีดจำกัดที่ตั้งไว้ภายในช่วงเวลาที่กำหนด ซึ่งมีประโยชน์นอกเหนือจากการควบคุมสแปมในแชต
  • ตัวอย่างเช่น ในฟอร์มล็อกอิน เราสามารถใช้การจำกัดการใช้งานเพื่อยับยั้งการโจมตีแบบ brute force ขณะเดียวกันก็ยังยอมให้มีการเดาผิดได้เล็กน้อย
  • API endpoint ก็มักถูกกำหนดการจำกัดการใช้งานไว้เช่นกัน เพื่อไม่ให้ผู้ใช้คนเดียวผูกขาดทรัพยากร
    • หากอนุญาตให้ผู้ใช้เรียก API endpoint ที่มีต้นทุนสูงได้เพียง 100 ครั้งต่อนาที ก็สามารถใช้ตัวนับเพื่อติดตามจำนวน hit 100 ครั้งต่อนาที และบล็อกคำขอหลังจากนั้น
    • นี่คือหนึ่งในอัลกอริทึมการจำกัดการใช้งานที่ง่ายที่สุด ซึ่งเรียกว่า Fixed Window Limiter
    • เป็นวิธีทั่วไปในการควบคุมทราฟฟิกของบริการ

อัลกอริทึม Fixed windows

  • จำกัดจำนวนคำขอภายในช่วงเวลาคงที่ (window)
  • เมื่อต้นของแต่ละช่วงเวลา ตัวนับคำขอจะถูกรีเซ็ตกลับเป็น 0
  • ข้อดี
    • ติดตั้งใช้งานและทำความเข้าใจได้ง่าย
    • คาดเดาได้สำหรับผู้ใช้
  • ข้อเสีย
    • หากคำขอเริ่มขึ้นใกล้ช่วงท้ายของหน้าต่างเวลา อาจเกิด burst ของคำขอได้สูงสุดถึง 2 เท่าของขีดจำกัด
  • ตัวอย่างการใช้งานจริง: GitHub API ใช้ตัวจำกัดความเร็วแบบหน้าต่างเวลาคงที่ที่อนุญาตคำขอได้ 5,000 ครั้งต่อชั่วโมง
  • แทนที่จะกำหนดเวลาเริ่มของหน้าต่างด้วยช่วงคงที่ แต่ละหน้าต่างเวลาอาจถูกสร้างขึ้นจากเวลาที่ผู้ใช้ส่งคำขอครั้งแรกภายในหน้าต่างนั้น
  • ในแนวทางนี้ การแจ้งให้ผู้ใช้ทราบเวลาที่เหลือก่อนถึงหน้าต่างถัดไปมีความสำคัญเป็นพิเศษ

อัลกอริทึม Sliding windows

  • แทนที่จะเติมความจุใหม่ทั้งหมดในครั้งเดียว Sliding Window จะเติมความจุทีละหนึ่งคำขอ
  • ข้อดี
    • ทำให้การกระจายของทราฟฟิกคำขอราบรื่นขึ้น
    • เหมาะกับโหลดสูง
  • ข้อเสีย
    • คาดเดาได้ยากกว่าหน้าต่างเวลาคงที่สำหรับผู้ใช้
    • การเก็บ timestamp ของทุกคำขอใช้ทรัพยากรมาก
  • เนื่องจาก Sliding Window มีประโยชน์ที่สุดในสถานการณ์ที่มีทราฟฟิกสูง การที่อัลกอริทึมพื้นฐานใช้ทรัพยากรมากจึงกลายเป็นข้อเสียสำคัญ
  • ดังนั้น ตัวจำกัดความเร็วแบบ Sliding Window ในการใช้งานจริงส่วนใหญ่จึงใช้วิธีประมาณค่า (approximation)
  • วิธีประมาณค่านี้จะคำนวณจำนวนคำขอที่อนุญาตในหน้าต่างเวลาคงที่ก่อนหน้าและในหน้าต่างเวลาคงที่ปัจจุบัน แล้วถ่วงน้ำหนักคำขอที่อนุญาตในหน้าต่างก่อนหน้าตามสัดส่วนของช่วงทับซ้อนกับหน้าต่างเวลาแบบลอยตัวที่สิ้นสุด ณ เวลาปัจจุบัน
  • วิธีประมาณค่านี้จำกัดคำขอได้ใกล้เคียงกับอัตราเดิมมาก แต่มีประสิทธิภาพกว่ามาก
  • ตัวอย่างการใช้งานจริง: ตัวจำกัดความเร็วแบบปรับแต่งได้ของ Cloudflare ใช้ Approximate Sliding Window

อัลกอริทึม Token buckets

  • แทนที่จะคิดเป็นระยะเวลาของหน้าต่างเวลา ให้จินตนาการถึงบักเก็ตที่ถูกเติมด้วย "โทเค็น" ในอัตราคงที่
  • แต่ละคำขอจะดึงโทเค็นหนึ่งชิ้นออกจากบักเก็ตนี้ และหากบักเก็ตว่าง คำขอถัดไปจะถูกบล็อก
  • ความจุของบักเก็ตแสดงถึงจำนวนคำขอสูงสุดที่ burst สามารถรองรับได้
  • ช่วงเวลาการเติมกลับแสดงถึงช่วงห่างเฉลี่ยระยะยาวของคำขอที่อนุญาต
  • หนึ่งในข้อดีหลักของอัลกอริทึมนี้คือ สามารถกำหนด burst และความจุเฉลี่ยที่แยกจากกันได้โดยไม่ต้องใช้ตัวจำกัดความเร็วหลายตัว
  • ข้อดี
    • อนุญาต burst ของทราฟฟิกสูง แต่ยังคงบังคับใช้อัตราคำขอเฉลี่ยในระยะยาว
    • ยืดหยุ่นกว่าสำหรับผู้ใช้ โดยยอมให้ทราฟฟิกพุ่งสูงได้ภายในขอบเขตที่ยอมรับได้
  • ข้อเสีย
    • อธิบายข้อจำกัดและเวลาเติมกลับให้ผู้ใช้เข้าใจได้ยากกว่าหน้าต่างเวลาคงที่
  • ตัวอย่างการใช้งานจริง
    • Stripe ใช้ Token Bucket ที่มีขีดจำกัด 500 และช่วงเวลาการเติมกลับ 0.01 วินาทีต่อผู้ใช้ ทำให้สามารถรองรับคำขอได้ต่อเนื่อง 100 ครั้งต่อวินาที และรองรับ burst ได้สูงสุด 500 คำขอ
    • ฟรีเทียร์ของ GPT-3.5 จาก OpenAI ใช้ Token Bucket ที่มีขีดจำกัด 200 และช่วงเวลาการเติมกลับ 86400 วินาที/200 จึงจำกัดไว้ที่ 200 คำขอต่อวัน

สิ่งที่ควรพิจารณาเมื่อใช้ Rate Limit

  • ต้องมี persistent storage สำหรับ rate limiter
  • หากการเชื่อมต่อของเซิร์ฟเวอร์ไปยัง persistent storage ล้มเหลว ควรอนุญาตทุกคำขอแทนที่จะบล็อก
  • อาจเลือกควบคุม burst traffic เพิ่มเติมได้
  • ต้องเลือกคีย์ที่เหมาะสม (เช่น user ID, API key เป็นต้น)
  • ควรแสดงข้อผิดพลาดการจำกัดความเร็วที่เป็นประโยชน์ (เช่น เวลาที่ต้องรอก่อนส่งคำขอครั้งถัดไป, สถานะ HTTP 429, response header อย่าง x-ratelimit-* เป็นต้น)

2 ความคิดเห็น

 
humblebee 2024-05-18

พออ่านบทความสรุปเป็นภาษาเกาหลีแล้วก็คิดว่า "โอเค เข้าใจว่าคืออะไร แต่เนื้อหามันก็เหมือน ๆ กันไม่ใช่เหรอ?" แต่พอได้ไปอ่านบทความต้นฉบับตามลิงก์แล้ว อธิบายได้ดีมากจริง ๆ และการทำภาพให้เห็นภาพก็ถูกใจมากด้วย! 👍👍👍

 
GN⁺ 2024-05-18
ความคิดเห็นจาก Hacker News

สรุปรวมความคิดเห็นจาก Hacker News

  • ข้อพิจารณาเพิ่มเติมจากประสบการณ์อันยาวนาน:

    • Rate Limits: ไม่ได้ช่วยแก้ปัญหาความจุของแบ็กเอนด์ จึงควรมองว่าเป็นข้อจำกัดเชิงนโยบาย
    • Bad Traffic: ควรพิจารณามาตรการเพิ่มเติมนอกเหนือจาก rate limits แบบง่าย ๆ การจัดลำดับความสำคัญของทราฟฟิกตามสถานะการยืนยันตัวตน ลำดับความสำคัญของผู้ใช้/เซสชัน ฯลฯ มีประโยชน์
    • Communication: ควรเตรียมแนวทางรับมือเมื่อสำคัญลูกค้าหรือทีมภายในแตะถึง rate limits
    • Concertina Effects: ควรเพิ่ม deterministic offset ให้กับหน้าต่างของผู้ใช้/เซสชันแต่ละราย เพื่อหลีกเลี่ยงไม่ให้ fixed window ทั้งหมดหรือ sliding window จำนวนมากหมดอายุพร้อมกัน
  • ในสภาพแวดล้อมแบบมัลติเทนเนนต์ การทำ fair queueing เป็นแนวทางที่เหมาะที่สุดในการป้องกันการโจมตีแบบ DoS: จัดสรรคิวของตัวเองให้แต่ละไคลเอนต์ แล้วให้ background routine วนตรวจแต่ละคิวซ้ำ ๆ เพื่อประมวลผลคำขอ ไคลเอนต์ที่ส่งคำขอสแปมจะทำให้มีเพียงคิวของตัวเองที่แออัด

  • ประสบการณ์ในการพัฒนาโค้ดฝั่งไคลเอนต์: สงสัยมาตลอดว่ากลยุทธ์ backoff แบบใดดีที่สุดเมื่อชน rate limit การได้อ่าน trade-off จากมุมมองของบริการเป็นเรื่องน่าสนใจ

  • ข้อความแสดงความยินดี: เป็นงานภาพประกอบที่ดีที่สุดสำหรับคอนเทนต์สั้น ๆ ให้ข้อมูลแน่นและสรุปประเด็นได้ดีมาก

  • อัลกอริทึม GCRA: คิดว่าเป็นอัลกอริทึมที่ดีกว่าสำหรับ rate limiting และอยากให้เป็นที่รู้จักและถูกใช้งานแพร่หลายกว่านี้

  • งานที่ยอดเยี่ยม: สัมผัสได้ว่ามีการทุ่มเวลาและความพยายามไปกับโพสต์นี้มาก ทำได้ดีมาก

  • ปัญหา rate-limiting บน AWS Lambda: เคยพยายามทำ rate-limiting ใน NodeJS แต่บน AWS Lambda ตัวจับเวลาทำงานแปลก ๆ จนเกินเป้าหมาย ผ่านในการทดสอบบนเครื่องโลคัลแต่ล้มเหลวบน Lambda ไม่แน่ใจว่าเป็นปัญหาของตัวจับเวลาหรือของไลบรารี

  • การรับมือเมื่อเลเยอร์ rate limiting อิ่มตัว: สงสัยว่ามีตัวเลือกอื่นนอกจาก CF หรือไม่ และอยากรู้ว่ากฎ nftable มีประสิทธิภาพแค่ไหนในการป้องกันการโจมตีแบบ DoS บน VPS ขนาดเล็ก

  • ทรัพยากรที่เคยอยากได้ในหลายช่วงเวลา: เป็นทรัพยากรที่ตลอดเส้นทางอาชีพเคยต้องการหลายครั้ง ตอนนี้ดีใจที่มันมีอยู่แล้ว

  • แฟนข้อมูลภาพ: สงสัยว่าใช้ D3 อยู่หรือไม่