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

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

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

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

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

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

สาเหตุที่ฟังก์ชันที่ทำงานตามเหตุการณ์ดำเนินการไม่สำเร็จ

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

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

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

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

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

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

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

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

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

  1. จากหน้าCloud Functionsภาพรวม ให้คลิกชื่อฟังก์ชันที่กำลังอัปเดตเพื่อเปิดหน้าจอรายละเอียดฟังก์ชัน จากนั้นเลือกแก้ไขจากแถบเมนูเพื่อแสดงแผงทริกเกอร์
  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);
});

ทําให้ฟังก์ชันที่ทํางานตามเหตุการณ์ซึ่งสามารถลองใหม่ได้เป็นแบบ idempotent

ฟังก์ชันที่ทำงานตามเหตุการณ์ซึ่งสามารถลองใหม่ได้ต้องเป็นแบบ idempotent ต่อไปนี้คือหลักเกณฑ์ทั่วไปในการทําให้ฟังก์ชันดังกล่าวเป็นแบบ idempotent

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

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

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

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

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

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

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