ลองใช้ฟังก์ชันอะซิงโครนัสอีกครั้ง

เอกสารนี้อธิบายวิธีขอฟังก์ชันพื้นหลังแบบไม่พร้อมกัน (ไม่ใช่ HTTPS) เพื่อลองดำเนินการล้มเหลวอีกครั้ง

ความหมายของการลองอีกครั้ง

Cloud Functions จะให้การดำเนินการอย่างน้อย 1 ครั้งของฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์สำหรับแต่ละเหตุการณ์ที่เกิดจากแหล่งที่มาของเหตุการณ์ โดยค่าเริ่มต้น หากการเรียกใช้ฟังก์ชันสิ้นสุดโดยมีข้อผิดพลาด จะไม่มีการเรียกใช้ฟังก์ชันดังกล่าวอีกและเหตุการณ์จะหายไป เมื่อคุณเปิดใช้การลองอีกครั้งในฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ Cloud Functions จะพยายามเรียกใช้ฟังก์ชันที่ล้มเหลวซ้ำจนกว่าจะเสร็จสมบูรณ์หรือกรอบเวลาการลองใหม่หมดอายุ

สำหรับฟังก์ชันรุ่นที่ 2 กรอบเวลาลองอีกครั้งนี้จะหมดอายุหลังจากผ่านไป 24 ชั่วโมง สำหรับฟังก์ชันรุ่นที่ 1 ฟังก์ชันดังกล่าวจะหมดอายุหลังจาก 7 วัน Cloud Functions จะพยายามดำเนินการกับฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ที่สร้างขึ้นใหม่อีกครั้งโดยใช้กลยุทธ์ Exponential Backoff โดยมีการย้อนกลับเพิ่มขึ้นระหว่าง 10-600 วินาที นโยบายนี้จะใช้กับฟังก์ชันใหม่ เมื่อคุณทำให้ฟังก์ชันใช้งานได้เป็นครั้งแรก โดยจะไม่มีผลย้อนหลังกับฟังก์ชันที่มีอยู่ที่ทำให้ใช้งานได้ครั้งแรกก่อนที่การเปลี่ยนแปลงที่อธิบายไว้ในบันทึกประจำรุ่นนี้จะมีผล แม้ว่าคุณจะทำให้ฟังก์ชันใช้งานได้อีกครั้งก็ตาม

เมื่อไม่ได้เปิดใช้การพยายามซ้ำสำหรับฟังก์ชัน ซึ่งเป็นค่าเริ่มต้น ฟังก์ชันจะรายงานเสมอว่าดำเนินการสำเร็จ และรหัสตอบกลับ 200 OK อาจปรากฏในบันทึก ซึ่งจะเกิดขึ้นแม้ว่าฟังก์ชันจะเกิดข้อผิดพลาดก็ตาม อย่าลืมรายงานข้อผิดพลาดอย่างเหมาะสม เพื่อให้เข้าใจง่ายเมื่อฟังก์ชันพบข้อผิดพลาด

เหตุใดฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์จึงไม่สําเร็จ

ในบางกรณีที่เกิดขึ้นไม่บ่อยนัก ฟังก์ชันอาจปิดก่อนกำหนดเนื่องจากข้อผิดพลาดภายใน และโดยค่าเริ่มต้น ฟังก์ชันอาจทำงานหรือไม่ลองทำใหม่โดยอัตโนมัติ

โดยทั่วไปแล้ว ฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์อาจดำเนินการไม่สำเร็จเนื่องจากมีการแสดงข้อผิดพลาดในโค้ดฟังก์ชัน ปัญหานี้อาจเกิดจากสาเหตุต่อไปนี้

  • ฟังก์ชันดังกล่าวมีข้อบกพร่องและรันไทม์จะส่งข้อยกเว้น
  • ฟังก์ชันนี้เข้าถึงปลายทางของบริการไม่ได้ หรือหมดเวลาขณะพยายามดำเนินการ
  • ฟังก์ชันตั้งใจส่งข้อยกเว้น (เช่น เมื่อพารามิเตอร์ตรวจสอบความถูกต้องไม่สำเร็จ)
  • ฟังก์ชัน Node.js จะแสดงผลสัญญาที่ถูกปฏิเสธหรือส่งค่าที่ไม่ใช่ null ไปยัง Callback

ในกรณีเหล่านี้ ฟังก์ชันจะหยุดการดำเนินการโดยค่าเริ่มต้นและระบบจะทิ้งเหตุการณ์ หากต้องการลองใช้ฟังก์ชันอีกครั้งเมื่อเกิดข้อผิดพลาด คุณจะเปลี่ยนนโยบายการลองใหม่เริ่มต้นได้โดยการตั้งค่าพร็อพเพอร์ตี้ "ลองใหม่เมื่อล้มเหลว" ซึ่งจะทำให้มีการลองซ้ำเหตุการณ์ซ้ำๆ จนกว่าฟังก์ชันจะเสร็จสิ้น หรือหมดเวลาในการลองอีกครั้ง

เปิดหรือปิดใช้การลองใหม่

กำหนดค่าการลองใหม่จากคอนโซล

หากคุณกำลังสร้างฟังก์ชันใหม่ ให้ทำดังนี้

  1. จากหน้าจอสร้างฟังก์ชันในส่วนทริกเกอร์ แล้วเลือกประเภทเหตุการณ์ที่ทำหน้าที่เป็นทริกเกอร์สำหรับฟังก์ชัน
  2. เลือกช่องทำเครื่องหมายลองใหม่เมื่อล้มเหลวเพื่อเปิดใช้การลองใหม่

หากคุณกำลังอัปเดตฟังก์ชันที่มีอยู่ ให้ทำดังนี้

  1. จากหน้าภาพรวมฟังก์ชันระบบคลาวด์ ให้คลิกชื่อฟังก์ชันที่กำลังอัปเดตเพื่อเปิดหน้าจอรายละเอียดฟังก์ชัน จากนั้นเลือกแก้ไขจากแถบเมนูเพื่อแสดงแผงทริกเกอร์
  2. เลือกหรือล้างช่องทำเครื่องหมาย ลองใหม่เมื่อล้มเหลว เพื่อเปิดหรือปิดใช้การลองใหม่

กำหนดค่าการลองใหม่จากโค้ดฟังก์ชัน

คุณเปิดใช้การลองใหม่ในโค้ดสำหรับฟังก์ชันได้ด้วย Cloud Functions for Firebase หากต้องการดำเนินการสำหรับฟังก์ชันพื้นหลัง เช่น functions.foo.onBar(myHandler); ให้ใช้ runWith และกำหนดค่านโยบายความล้มเหลว

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

การตั้งค่า true ตามที่แสดงจะกําหนดค่าฟังก์ชันให้ลองอีกครั้งเมื่อล้มเหลว

แนวทางปฏิบัติแนะนำ

ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำสำหรับการลองใหม่

ใช้การลองอีกครั้งเพื่อจัดการข้อผิดพลาดชั่วคราว

เนื่องจากมีการพยายามดำเนินการกับฟังก์ชันอย่างต่อเนื่องจนกว่าจะดำเนินการสำเร็จ เราจึงควรกำจัดข้อผิดพลาดถาวรอย่างเช่นข้อบกพร่องออกจากโค้ดผ่านการทดสอบก่อนเปิดใช้การดำเนินการอีกครั้ง การลองใหม่คือวิธีที่ดีที่สุดในการจัดการกับการทำงานล้มเหลวเป็นบางครั้งหรือชั่วคราว ซึ่งมีโอกาสสูงที่จะแก้ปัญหาได้เมื่อมีการลองใหม่ เช่น ปลายทางของบริการที่ไม่สม่ำเสมอหรือหมดเวลา

กำหนดเงื่อนไขสิ้นสุดเพื่อหลีกเลี่ยงการวนลูปซ้ำแบบไม่สิ้นสุด

แนวทางปฏิบัติแนะนำคือปกป้องฟังก์ชันจากการวนซ้ำอย่างต่อเนื่องเมื่อใช้การลองใหม่ ซึ่งทำได้โดยใส่เงื่อนไขสิ้นสุดที่กำหนดไว้อย่างชัดเจนก่อนที่ฟังก์ชันจะเริ่มประมวลผล โปรดทราบว่าเทคนิคนี้จะใช้ได้เมื่อฟังก์ชันเริ่มต้นสําเร็จเท่านั้น และประเมินเงื่อนไขปลายทางได้

วิธีที่ง่ายแต่มีประสิทธิภาพคือการยกเลิกเหตุการณ์ที่มีการประทับเวลาเก่ากว่าเวลาที่เจาะจง วิธีนี้จะช่วยหลีกเลี่ยงการดำเนินการที่มากเกินไปในกรณีที่ความล้มเหลวเกิดขึ้นอย่างต่อเนื่องหรือยาวนานกว่าที่คาดไว้

ตัวอย่างเช่น ข้อมูลโค้ดนี้จะทิ้งเหตุการณ์ทั้งหมดที่เก่ากว่า 10 วินาที

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

ใช้ catch พร้อมสัญญา

หากฟังก์ชันเปิดใช้การลองอีกครั้งแล้ว ข้อผิดพลาดที่ไม่มีการจัดการจะทริกเกอร์การลองอีกครั้ง ตรวจสอบว่าโค้ดบันทึกข้อผิดพลาดที่ไม่ควรส่งผลให้มีการลองอีกครั้ง

ตัวอย่างสิ่งที่คุณควรทำมีดังนี้

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

กำหนดให้ฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ซึ่งลองอีกครั้งได้เป็นเอกลักษณ์

ฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ซึ่งลองใช้ซ้ำได้จะต้องเป็นเอกลักษณ์ หลักเกณฑ์ทั่วไปในการสร้างข้อมูลประจำตัวของฟังก์ชันมีดังนี้

  • API ภายนอกจำนวนมาก (เช่น Stripe) ให้คุณใส่คีย์รหัสเป็นพารามิเตอร์ได้ หากคุณใช้ API ดังกล่าว คุณควรใช้รหัสเหตุการณ์เป็นคีย์ประจำตัว
  • กระบวนการทำงานมักจะได้ผลดีกับการนำส่งอย่างน้อย 1 ครั้ง เพราะทำให้ลองอีกครั้งได้อย่างปลอดภัย ดังนั้น แนวทางปฏิบัติที่ดีที่สุดโดยทั่วไปสำหรับการเขียนโค้ดที่เชื่อถือได้คือการรวมอัตราการหยุดนิ่งเข้ากับการลองใหม่
  • ตรวจสอบว่าโค้ดเป็นรหัสภายใน เช่น
    • ดูให้แน่ใจว่าการเปลี่ยนแปลงอาจเกิดขึ้นได้มากกว่า 1 ครั้งโดยไม่เปลี่ยนผลลัพธ์
    • ค้นหาสถานะฐานข้อมูลในธุรกรรมก่อนเปลี่ยนแปลงสถานะ
    • อย่าลืมตรวจสอบว่าผลข้างเคียงทั้งหมดมาจากตัวมันเอง
  • กำหนดการตรวจสอบธุรกรรมภายนอกฟังก์ชัน โดยไม่ต้องขึ้นอยู่กับโค้ด เช่น คงสถานะไว้ในบางจุดที่บันทึกไว้ว่ารหัสเหตุการณ์หนึ่งๆ ได้รับการประมวลผลแล้ว
  • จัดการกับการเรียกฟังก์ชันที่ซ้ำกันนอกขอบเขต เช่น มีกระบวนการล้างข้อมูลแยกต่างหากซึ่งจะล้างออกหลังจากการเรียกใช้ฟังก์ชันซ้ำ

กำหนดค่านโยบายการลองอีกครั้ง

คุณอาจต้องกำหนดค่านโยบายลองอีกครั้งโดยตรง ทั้งนี้ขึ้นอยู่กับความต้องการของ Cloud Function ซึ่งจะช่วยให้คุณตั้งค่าชุดค่าผสมของข้อมูลต่อไปนี้

  • ลดกรอบเวลาการลองใหม่จาก 7 วันให้เหลือเพียง 10 นาที
  • เปลี่ยนเวลา Backoff ต่ำสุดและสูงสุดสำหรับกลยุทธ์การลองใหม่แบบ Exponential Backoff
  • โปรดเปลี่ยนกลยุทธ์การลองใหม่เพื่อลองอีกครั้ง
  • กำหนดค่าหัวข้อจดหมายที่ส่งไม่ได้
  • กำหนดจำนวนครั้งสูงสุดและต่ำสุดในการนำส่ง

วิธีกำหนดค่านโยบายการลองอีกครั้ง

  1. เขียนฟังก์ชัน HTTP
  2. ใช้ Pub/Sub API เพื่อสร้างการสมัครใช้บริการ Pub/Sub โดยระบุ URL ของฟังก์ชันเป็นเป้าหมาย

ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า Pub/Sub โดยตรงได้จากเอกสารประกอบเกี่ยวกับ Pub/Sub เกี่ยวกับการจัดการความล้มเหลว