เอกสารนี้อธิบายวิธีขอฟังก์ชันพื้นหลังแบบไม่พร้อมกัน (ไม่ใช่ HTTPS) เพื่อลองดำเนินการล้มเหลวอีกครั้ง
ความหมายของการลองอีกครั้ง
Cloud Functions จะให้การดำเนินการอย่างน้อย 1 ครั้งของฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์สำหรับแต่ละเหตุการณ์ที่เกิดจากแหล่งที่มาของเหตุการณ์ โดยค่าเริ่มต้น หากการเรียกใช้ฟังก์ชันสิ้นสุดโดยมีข้อผิดพลาด จะไม่มีการเรียกใช้ฟังก์ชันดังกล่าวอีกและเหตุการณ์จะหายไป เมื่อคุณเปิดใช้การลองอีกครั้งในฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ Cloud Functions จะพยายามเรียกใช้ฟังก์ชันที่ล้มเหลวซ้ำจนกว่าจะเสร็จสมบูรณ์หรือกรอบเวลาการลองใหม่หมดอายุ
สำหรับฟังก์ชันรุ่นที่ 2 กรอบเวลาลองอีกครั้งนี้จะหมดอายุหลังจากผ่านไป 24 ชั่วโมง สำหรับฟังก์ชันรุ่นที่ 1 ฟังก์ชันดังกล่าวจะหมดอายุหลังจาก 7 วัน Cloud Functions จะพยายามดำเนินการกับฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์ที่สร้างขึ้นใหม่อีกครั้งโดยใช้กลยุทธ์ Exponential Backoff โดยมีการย้อนกลับเพิ่มขึ้นระหว่าง 10-600 วินาที นโยบายนี้จะใช้กับฟังก์ชันใหม่ เมื่อคุณทำให้ฟังก์ชันใช้งานได้เป็นครั้งแรก โดยจะไม่มีผลย้อนหลังกับฟังก์ชันที่มีอยู่ที่ทำให้ใช้งานได้ครั้งแรกก่อนที่การเปลี่ยนแปลงที่อธิบายไว้ในบันทึกประจำรุ่นนี้จะมีผล แม้ว่าคุณจะทำให้ฟังก์ชันใช้งานได้อีกครั้งก็ตามเมื่อไม่ได้เปิดใช้การพยายามซ้ำสำหรับฟังก์ชัน ซึ่งเป็นค่าเริ่มต้น ฟังก์ชันจะรายงานเสมอว่าดำเนินการสำเร็จ และรหัสตอบกลับ 200 OK
อาจปรากฏในบันทึก ซึ่งจะเกิดขึ้นแม้ว่าฟังก์ชันจะเกิดข้อผิดพลาดก็ตาม อย่าลืมรายงานข้อผิดพลาดอย่างเหมาะสม เพื่อให้เข้าใจง่ายเมื่อฟังก์ชันพบข้อผิดพลาด
เหตุใดฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์จึงไม่สําเร็จ
ในบางกรณีที่เกิดขึ้นไม่บ่อยนัก ฟังก์ชันอาจปิดก่อนกำหนดเนื่องจากข้อผิดพลาดภายใน และโดยค่าเริ่มต้น ฟังก์ชันอาจทำงานหรือไม่ลองทำใหม่โดยอัตโนมัติ
โดยทั่วไปแล้ว ฟังก์ชันที่ขับเคลื่อนด้วยเหตุการณ์อาจดำเนินการไม่สำเร็จเนื่องจากมีการแสดงข้อผิดพลาดในโค้ดฟังก์ชัน ปัญหานี้อาจเกิดจากสาเหตุต่อไปนี้
- ฟังก์ชันดังกล่าวมีข้อบกพร่องและรันไทม์จะส่งข้อยกเว้น
- ฟังก์ชันนี้เข้าถึงปลายทางของบริการไม่ได้ หรือหมดเวลาขณะพยายามดำเนินการ
- ฟังก์ชันตั้งใจส่งข้อยกเว้น (เช่น เมื่อพารามิเตอร์ตรวจสอบความถูกต้องไม่สำเร็จ)
- ฟังก์ชัน Node.js จะแสดงผลสัญญาที่ถูกปฏิเสธหรือส่งค่าที่ไม่ใช่
null
ไปยัง Callback
ในกรณีเหล่านี้ ฟังก์ชันจะหยุดการดำเนินการโดยค่าเริ่มต้นและระบบจะทิ้งเหตุการณ์ หากต้องการลองใช้ฟังก์ชันอีกครั้งเมื่อเกิดข้อผิดพลาด คุณจะเปลี่ยนนโยบายการลองใหม่เริ่มต้นได้โดยการตั้งค่าพร็อพเพอร์ตี้ "ลองใหม่เมื่อล้มเหลว" ซึ่งจะทำให้มีการลองซ้ำเหตุการณ์ซ้ำๆ จนกว่าฟังก์ชันจะเสร็จสิ้น หรือหมดเวลาในการลองอีกครั้ง
เปิดหรือปิดใช้การลองใหม่
กำหนดค่าการลองใหม่จากคอนโซล
หากคุณกำลังสร้างฟังก์ชันใหม่ ให้ทำดังนี้
- จากหน้าจอสร้างฟังก์ชันในส่วนทริกเกอร์ แล้วเลือกประเภทเหตุการณ์ที่ทำหน้าที่เป็นทริกเกอร์สำหรับฟังก์ชัน
- เลือกช่องทำเครื่องหมายลองใหม่เมื่อล้มเหลวเพื่อเปิดใช้การลองใหม่
หากคุณกำลังอัปเดตฟังก์ชันที่มีอยู่ ให้ทำดังนี้
- จากหน้าภาพรวมฟังก์ชันระบบคลาวด์ ให้คลิกชื่อฟังก์ชันที่กำลังอัปเดตเพื่อเปิดหน้าจอรายละเอียดฟังก์ชัน จากนั้นเลือกแก้ไขจากแถบเมนูเพื่อแสดงแผงทริกเกอร์
- เลือกหรือล้างช่องทำเครื่องหมาย ลองใหม่เมื่อล้มเหลว เพื่อเปิดหรือปิดใช้การลองใหม่
กำหนดค่าการลองใหม่จากโค้ดฟังก์ชัน
คุณเปิดใช้การลองใหม่ในโค้ดสำหรับฟังก์ชันได้ด้วย 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
- โปรดเปลี่ยนกลยุทธ์การลองใหม่เพื่อลองอีกครั้ง
- กำหนดค่าหัวข้อจดหมายที่ส่งไม่ได้
- กำหนดจำนวนครั้งสูงสุดและต่ำสุดในการนำส่ง
วิธีกำหนดค่านโยบายการลองอีกครั้ง
- เขียนฟังก์ชัน HTTP
- ใช้ Pub/Sub API เพื่อสร้างการสมัครใช้บริการ Pub/Sub โดยระบุ URL ของฟังก์ชันเป็นเป้าหมาย
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า Pub/Sub โดยตรงได้จากเอกสารประกอบเกี่ยวกับ Pub/Sub เกี่ยวกับการจัดการความล้มเหลว