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