เอกสารนี้อธิบายวิธีขอฟังก์ชันพื้นหลังแบบไม่พร้อมกัน (ไม่ใช่ 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
กับ Promise
หากฟังก์ชันเปิดใช้การลองอีกครั้ง ข้อผิดพลาดที่ไม่ได้รับการจัดการจะทริกเกอร์การลองอีกครั้ง ตรวจสอบว่าโค้ดของคุณบันทึกข้อผิดพลาดที่ไม่ควรส่งผลให้มีการลองอีกครั้ง
ตัวอย่างสิ่งที่ควรทำมีดังนี้
return doFooAsync().catch((err) => {
if (isFatal(err)) {
console.error(`Fatal error ${err}`);
}
return Promise.reject(err);
});
ทำให้ฟังก์ชันที่ทำงานตามเหตุการณ์ซึ่งสามารถลองใหม่ได้เป็นแบบซ้ำ
ฟังก์ชันที่ทำงานตามเหตุการณ์ซึ่งสามารถลองใหม่ได้ต้องเป็นแบบ idempotent ต่อไปนี้คือหลักเกณฑ์ทั่วไปในการทําให้ฟังก์ชันดังกล่าวเป็นแบบ idempotent
- API ภายนอกหลายรายการ (เช่น Stripe) ให้คุณระบุคีย์แบบซ้ำได้ในฐานะพารามิเตอร์ หากใช้ API ดังกล่าว คุณควรใช้รหัสเหตุการณ์เป็นคีย์ที่ซ้ำกันไม่ได้
- การทำงานซ้ำทำงานได้ดีกับการนำส่งอย่างน้อย 1 ครั้ง เนื่องจากทำให้สามารถลองใหม่ได้อย่างปลอดภัย ดังนั้นแนวทางปฏิบัติแนะนำทั่วไปในการเขียนโค้ดที่เชื่อถือได้คือการรวมการทําซ้ำได้กับการทำซ้ำ
- ตรวจสอบว่าโค้ดของคุณเป็นแบบ idempotent ภายใน เช่น
- ตรวจสอบว่าเกิดการกลายพันธุ์ได้มากกว่า 1 ครั้งโดยไม่เปลี่ยนผลลัพธ์
- ค้นหาสถานะฐานข้อมูลในธุรกรรมก่อนที่จะเปลี่ยนสถานะ
- ตรวจสอบว่าผลข้างเคียงทั้งหมดเป็นแบบ idempotent
- ใช้การตรวจสอบธุรกรรมนอกฟังก์ชันโดยแยกจากโค้ด เช่น เก็บสถานะไว้ที่ใดที่หนึ่งเพื่อบันทึกว่ารหัสเหตุการณ์หนึ่งๆ ได้รับการประมวลผลแล้ว
- จัดการกับการเรียกฟังก์ชันที่ซ้ำกันนอกแบนด์ เช่น มีกระบวนการล้างข้อมูลแยกต่างหากที่จะล้างข้อมูลหลังจากการเรียกฟังก์ชันซ้ำ
กำหนดค่านโยบายการลองใหม่
คุณอาจต้องกําหนดค่านโยบายการลองอีกครั้งโดยตรง ทั้งนี้ขึ้นอยู่กับความต้องการฟังก์ชัน ซึ่งจะช่วยให้คุณตั้งค่าชุดค่าผสมต่อไปนี้ได้
- กรอบเวลาการลองอีกครั้งจะสั้นลงจาก 7 วันเหลือเพียง 10 นาที
- เปลี่ยนเวลาพักขั้นต่ำและสูงสุดสําหรับกลยุทธ์การพักแบบทวีคูณเพื่อลองอีกครั้ง
- เปลี่ยนกลยุทธ์การลองใหม่ให้ลองใหม่ทันที
- กำหนดค่าหัวข้อจดหมายที่ส่งไม่ได้
- กำหนดจำนวนครั้งสูงสุดและต่ำสุดในการพยายามนำส่ง
วิธีกำหนดค่านโยบายการลองใหม่
- เขียนฟังก์ชัน HTTP
- ใช้ Pub/Sub API เพื่อสร้างการสมัครใช้บริการ Pub/Sub โดยระบุ URL ของฟังก์ชันเป็นเป้าหมาย
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า Pub/Sub โดยตรงได้ในเอกสารประกอบของ Pub/Sub เกี่ยวกับการจัดการข้อผิดพลาด