รับมือข้อจำกัด UrlFetchApp ใน Apps Script ป้องกันข้อมูลหายด้วยระบบ Retry และ DLQ
เรียนรู้วิธีแก้ปัญหา API Rate Limit 429 และป้องกันข้อมูลสูญหายใน Google Apps Script ด้วย 4 เลเยอร์สำคัญ พร้อมเทคนิค Exponential Backoff และ Dead-Letter Queue

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- งานรันประจำคืนทำข้อมูลตกหล่นถึง 300 แถวเงียบๆ จากปัญหา 429 Rate Limited
- ข้อจำกัด UrlFetchApp ให้บริการ 20,000 ครั้ง/วัน สำหรับบัญชีทั่วไป และ 100,000 ครั้ง/วัน สำหรับ Workspace
- ตั้งค่า muteHttpExceptions: true เพื่อให้ระบบสามารถดักจับสถานะโค้ดข้อผิดพลาดและทำการลองใหม่ได้
- การใช้ Dead-Letter Queue บันทึกรายการที่ล้มเหลวลงในชีตช่วยป้องกันไม่ให้ข้อมูลสูญหายถาวร
ปัญหาข้อมูลสูญหายอย่างเงียบๆ มักเกิดขึ้นได้เสมอเมื่อระบบรันงานอัตโนมัติในตอนกลางคืน เช่นเดียวกับเหตุการณ์ที่งานอัปเดตข้อมูลผลิตภัณฑ์ทำแถวข้อมูลหายไปเกือบ 300 แถวโดยไม่มีการแจ้งเตือนใดๆ สาเหตุหลักมาจาก API ฝั่งต้นทางส่งสัญญาณเตือน 429 Rate-Limited กลับมา ทำให้คำสั่ง UrlFetchApp.fetch เกิดข้อผิดพลาด ลูปการทำงานหยุดกลางคัน และเมื่อถึงรอบรันถัดไป ข้อมูลที่ตกหล่นก็หายไปเลยอย่างถาวร
ทุกการเชื่อมต่อผ่าน UrlFetchApp ย่อมต้องเผชิญกับปัญหานี้ในที่สุด ทางแก้จึงไม่ใช่แค่ฟังก์ชันฉลาดๆ เพียงตัวเดียว แต่ต้องอาศัยกลไก 4 เลเยอร์ที่จะช่วยป้องกันไม่ให้ความล้มเหลวชั่วคราวกลายเป็นการสูญหายของข้อมูล โดยโครงสร้างที่ใช้งานจริงประกอบด้วยแนวทางเหล่านี้
ก่อนจะเริ่มลงมือเขียนโค้ด จำเป็นต้องเข้าใจข้อจำกัดต่างๆ ของระบบให้ดีเสียก่อน โดยแต่ละคำขอจะมีข้อจำกัดเวลาหมดอายุที่ 60 วินาที และจำกัดขนาดข้อมูลไว้ที่ 50 เมกะไบต์ต่อเที่ยว นอกจากนี้ยังมีข้อจำกัดเรื่องการเรียกพร้อมกัน (Concurrent calls) ต่อสคริปต์ที่อยู่ที่ประมาณ 10 ถึง 20 คำขอ ซึ่งหากทำแบบคู่ขนานโดยไม่ระมัดระวัง จะทำให้เกิดข้อผิดพลาด Service invoked too many times ทันที

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
รากฐานสำคัญเริ่มต้นที่บรรทัดคำสั่ง muteHttpExceptions: true เพราะหากปราศจากสิ่งนี้ สถานะ 429 จะโยนข้อผิดพลาดออกไปก่อนที่ระบบลองใหม่ (Retry) จะทันได้ตรวจสอบรหัสสถานะ โดยควรตั้งค่าให้ลองใหม่เฉพาะเมื่อเจอสถานะ 429 และ 5xx เท่านั้น เนื่องจากสถานะ 400 หรือ 401 จะไม่สามารถแก้ไขได้ด้วยตัวเอง จึงควรแสดงผลแจ้งเตือนทันที พร้อมทั้งใส่ Jitter (การหน่วงเวลาสุ่ม 0-500 มิลลิวินาที) เพื่อป้องกันไม่ให้ชุดสคริปต์จำนวนมากลองส่งคำขอซ้ำพร้อมกันจนไปถล่ม API
การทำความเข้าใจเรื่อง Rate Limit และ Quota เป็นหัวใจสำคัญของการพัฒนาสคริปต์บนคลาวด์อย่าง Google Apps Script เนื่องจากทรัพยากรมีจำกัด การออกแบบระบบที่มีความยืดหยุ่น (Resilient Architecture) จึงช่วยลดภาระของเซิร์ฟเวอร์ปลายทาง และป้องกันไม่ให้แอปพลิเคชันหยุดชะงักเมื่อมีปริมาณข้อมูลจำนวนมาก
สำหรับการเรียกใช้งานที่มีความอิสระต่อกันจำนวนมาก การใช้ UrlFetchApp.fetchAll จะช่วยรวบรวมคำขอส่งเป็นชุดเดียวแทนการวนลูปทีละรายการ ซึ่งช่วยประหยัดโควต้าได้อย่างมีประสิทธิภาพมากกว่า โดยควรจำกัดขนาดชุดข้อมูลอยู่ที่ประมาณ 10 ถึง 20 คำขอต่อรอบ เพื่อไม่ให้เกินขีดจำกัดการเชื่อมต่อพร้อมกัน
เลเยอร์สุดท้ายคือสิ่งที่จะช่วยกู้คืนข้อมูล 300 แถวที่เคยหายไป นั่นคือ Dead-Letter Queue เมื่อการลองใหม่ทั้งหมดล้มเหลว แทนที่จะปล่อยให้ข้อความหลุดลอยไป ให้เขียนบันทึกคำขอที่ล้มเหลวลงใน Google Sheets เพื่อให้สามารถนำกลับมาประมวลผลซ้ำ (Replay) ได้ตามต้องการ
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น