แคมเปญลดราคาทำให้แชท LINE ทะลักจน API ของ Salesforce ปฏิเสธการเชื่อมต่อ: ออกแบบ Rate Limit และ Retry ให้รอด

สรุปสั้น ๆ
ระบบองค์กรอย่าง Salesforce, HubSpot หรือ SAP มักจำกัดจำนวน API request ต่อช่วงเวลาเพื่อป้องกันเซิร์ฟเวอร์ล่ม เมื่อแคมเปญทำให้ดีลจากแชท LINE พุ่งสูงพร้อมกัน การยิงข้อมูลเข้าไปไม่หยุดจะโดนปฏิเสธและอาจทำข้อมูลหาย การออกแบบคิวข้อความ + exponential backoff คือทางแก้มาตรฐานที่ป้องกันปัญหานี้ได้
ทีมการตลาดของแบรนด์เครื่องใช้ไฟฟ้าแห่งหนึ่งที่ผมเคยดูแลระบบให้ จัดแคมเปญลดราคา 11.11 แล้วปริมาณแชทที่ทักเข้ามาทาง LINE OA พุ่งจากปกติวันละ 300 ครั้ง เป็นเกือบ 4,000 ครั้งในวันเดียว ระบบเชื่อมข้อมูลที่เคยส่ง Lead เข้า Salesforce แบบ real-time ทุกครั้งที่มีการทัก เริ่มมีข้อความ error 'Too Many Requests' โผล่ขึ้นมาเป็นพัน ๆ รายการ
ปัญหาไม่ได้เกิดจากระบบพัง แต่เกิดจาก Salesforce จำกัดจำนวน API call ต่อช่วงเวลาไว้ตามแพ็กเกจที่องค์กรใช้ ทีมพัฒนาไม่เคยคำนวณไว้ก่อนว่าถ้าแคมเปญปังจริง ปริมาณ request จะเกินเพดานที่ตั้งไว้ ผลคือ Lead จากแชทหลายร้อยรายการในวันนั้นไม่เคยเข้า Salesforce เลย เพราะระบบแค่ยิงแล้วปล่อยผ่านเมื่อโดนปฏิเสธ ไม่มีกลไกส่งใหม่
บทความนี้ต่างจากเรื่อง batching ของ Conversion API ที่ยิงไปยังแพลตฟอร์มโฆษณา เพราะโฟกัสที่ API ของระบบองค์กรอย่าง CRM/ERP ซึ่งมีรูปแบบเพดานและพฤติกรรมการปฏิเสธที่ต่างกันออกไป จะพาดูวิธีออกแบบให้ข้อมูลไม่หายแม้ปริมาณพุ่งสูงกว่าที่คาดไว้มาก
ทำความเข้าใจเพดาน API ของระบบปลายทางก่อนเริ่มออกแบบ
ระบบองค์กรแต่ละตัวมีวิธีจำกัด rate ต่างกัน Salesforce จำกัดตามจำนวน API call ต่อ 24 ชั่วโมงรวมกับจำนวนคำขอต่อนาที ขึ้นกับแพ็กเกจที่องค์กรใช้ HubSpot จำกัดจำนวนคำขอต่อ 10 วินาทีในระดับที่ค่อนข้างเข้มงวดกว่า ส่วน SAP ผ่าน RFC/BAPI มักจำกัดตามจำนวน session ที่เปิดพร้อมกันมากกว่าจำนวนคำขอ
ก่อนออกแบบระบบเชื่อมต่อใด ๆ ควรถามผู้ดูแลระบบปลายทางหรือเอกสารทางการก่อนว่าเพดานที่แท้จริงคือเท่าไหร่ แล้วคำนวณว่าในวันที่แคมเปญปังที่สุดที่เคยเกิดขึ้น ปริมาณ request จะเกินเพดานนี้หรือไม่ ถ้าคำนวณไว้ล่วงหน้า จะออกแบบระบบรองรับได้ก่อนเกิดปัญหาจริง ไม่ใช่แก้หลังจากข้อมูลหายไปแล้ว
หัวใจของทางแก้: คิวข้อความ + exponential backoff
แทนที่จะยิง API เข้าระบบปลายทางทันทีทุกครั้งที่มีเหตุการณ์เกิดขึ้นในแชท ให้ส่งเหตุการณ์เข้าคิวข้อความ (message queue) ก่อนเสมอ แล้วให้ตัวประมวลผล (worker) ดึงจากคิวไปยิง API ตามอัตราที่ปลอดภัยกว่าเพดานที่ระบบปลายทางกำหนด วิธีนี้ทำให้ต่อให้มีเหตุการณ์เข้ามาพร้อมกันเป็นพันรายการ ระบบก็ค่อย ๆ ทยอยส่งแทนที่จะยิงพร้อมกันทั้งหมด
เมื่อ API ปลายทางตอบกลับว่าปฏิเสธเพราะเกิน rate limit ระบบไม่ควรลองซ้ำทันที เพราะจะยิ่งซ้ำเติมปัญหา ควรใช้หลัก exponential backoff คือรอนานขึ้นเรื่อย ๆ ในแต่ละครั้งที่ลองใหม่ เช่น รอ 5 วินาทีในครั้งแรก 15 วินาทีในครั้งที่สอง 45 วินาทีในครั้งที่สาม จนกว่าจะสำเร็จหรือถึงจำนวนครั้งสูงสุดที่กำหนดไว้ หลักการนี้คล้ายกับเรื่อง retry logic ที่อธิบายไว้ในการเชื่อม webhook เข้า ERP อย่างปลอดภัย เพียงแต่ในบริบทนี้เน้นที่การจัดการเพดานคำขอ ไม่ใช่แค่ป้องกัน order ซ้ำ
ถ้าคิวยาวเกินไป ควรจัดลำดับความสำคัญยังไง
| ประเภทเหตุการณ์ | ควรส่งก่อน/หลัง | เหตุผล |
|---|---|---|
| ปิดดีลแล้ว (มูลค่าสูง) | ส่งก่อนเสมอ | กระทบรายงานยอดขายและวงเงินเครดิตโดยตรง |
| ทักเข้ามาใหม่ (ยังไม่ปิด) | ส่งรองลงมา | สำคัญแต่ยังไม่กระทบเงินจริงทันที |
| อัปเดตข้อมูลทั่วไป เช่น อ่านข้อความ | ส่งท้ายสุดหรือ batch รวมทีหลัง | ไม่กระทบการตัดสินใจเร่งด่วนใด ๆ |
อย่าลืมระบบเฝ้าระวังคิวที่ยาวผิดปกติ
- ตั้ง alert เมื่อคิวข้อความค้างเกินจำนวนหรือเวลาที่กำหนดไว้ เพื่อให้ทีม IT รู้ทันทีว่าเกิดปัญหา ไม่ใช่รอให้ทีมขายมาบ่นว่าไม่เห็นข้อมูลใน CRM
- เก็บ log ของทุกครั้งที่ถูกปฏิเสธเพราะ rate limit พร้อมเวลาและจำนวนครั้งที่ retry เพื่อใช้วิเคราะห์ย้อนหลังว่าควรขยายเพดานแพ็กเกจ API หรือปรับปรุงตรรกะการส่งต่อ
- ทดสอบระบบด้วยการจำลองปริมาณ request สูงกว่าปกติหลายเท่าก่อนแคมเปญใหญ่จริง เพื่อให้มั่นใจว่าคิวและ backoff ทำงานตามที่ออกแบบไว้ ไม่ใช่รอให้เจอปัญหาจริงในวันแคมเปญแล้วค่อยแก้
สรุป
แคมเปญที่ประสบความสำเร็จจนแชททะลักเป็นสิ่งที่ทุกธุรกิจอยากให้เกิดขึ้น แต่ถ้าระบบเชื่อมต่อไม่ได้ออกแบบรองรับปริมาณสูงไว้ล่วงหน้า ความสำเร็จนั้นอาจแปลงเป็นข้อมูลที่หายไปเงียบ ๆ โดยไม่มีใครรู้จนสายเกินแก้
การมีคิวข้อความและ exponential backoff ไม่ใช่ความซับซ้อนเกินจำเป็น แต่เป็นการป้องกันความเสี่ยงที่คุ้มค่ากับความพยายาม โดยเฉพาะสำหรับธุรกิจที่พึ่งพาแคมเปญช่วงพีคเป็นรายได้หลักของปี
- เข้าใจเพดาน API ของระบบปลายทาง (Salesforce/HubSpot/SAP) ก่อนออกแบบการเชื่อมต่อ
- ใช้คิวข้อความ + exponential backoff แทนการยิง API ทันทีทุกครั้งไม่หยุด
- จัดลำดับความสำคัญของเหตุการณ์ในคิว และตั้ง alert เมื่อคิวค้างผิดปกติ
คำถามที่พบบ่อย
ต่างจากการทำ batching สำหรับ Conversion API ของแพลตฟอร์มโฆษณายังไง
หลักการคิวและ retry คล้ายกัน แต่บริบทต่างกัน Conversion API ของแพลตฟอร์มโฆษณาส่วนใหญ่ยอมรับการส่งเป็นชุด (batch) ได้ง่ายกว่า ส่วน API ขององค์กรอย่าง Salesforce หรือ SAP มักออกแบบมาสำหรับคำขอทีละรายการเป็นหลัก การจัดการเพดานจึงเน้นที่การหน่วงจังหวะส่งมากกว่าการรวมเป็นชุดใหญ่
ควรตั้งจำนวนครั้ง retry สูงสุดเท่าไหร่
ไม่มีตัวเลขตายตัว ขึ้นกับความสำคัญของข้อมูล ดีลมูลค่าสูงอาจตั้งให้ retry ได้มากกว่าและแจ้งเตือนทีมงานทันทีถ้ายังไม่สำเร็จ ส่วนข้อมูลทั่วไปอาจตั้งจำนวนครั้งน้อยกว่าและปล่อยผ่านได้ถ้าไม่สำคัญเร่งด่วน
ถ้าไม่มีทีมพัฒนาระบบคิวข้อความเอง มีทางเลือกอื่นไหม
เครื่องมือ iPaaS อย่าง Make หรือ Zapier มักมีกลไกจัดการ rate limit และ retry ในตัวอยู่แล้วระดับหนึ่ง เหมาะกับองค์กรที่ไม่มีทีมพัฒนาสร้างคิวข้อความเอง แต่ควรตรวจสอบรายละเอียดการตั้งค่าให้ตรงกับเพดานของระบบปลายทางที่ใช้จริง
การจำกัด rate ของเราเองที่ต้นทาง (ก่อนถึงปลายทาง) จำเป็นไหม
จำเป็นและควรทำควบคู่กับ retry logic เพราะการจำกัดอัตราส่งตั้งแต่ต้นทางช่วยลดโอกาสโดนปฏิเสธตั้งแต่แรก แทนที่จะปล่อยยิงเต็มที่แล้วค่อยจัดการตอนถูกปฏิเสธ ซึ่งสิ้นเปลืองทรัพยากรมากกว่า
จะรู้ได้ยังไงว่าเพดาน API ปัจจุบันพอสำหรับธุรกิจเรา
ให้ดูปริมาณการทักในวันที่แคมเปญปังที่สุดในอดีต แล้วคำนวณว่าถ้าทุกเหตุการณ์ต้องยิง API ทันที ปริมาณนั้นเกินเพดานที่ระบบปลายทางกำหนดหรือไม่ ถ้าใกล้เคียงหรือเกิน ควรวางระบบคิวไว้ล่วงหน้าก่อนแคมเปญใหญ่ครั้งต่อไป ไม่ใช่รอให้เกิดปัญหาก่อน
บทความที่เกี่ยวข้อง


