Tips & Tricks

เอกสารนี้อธิบายแนวทางปฏิบัติที่ดีที่สุดสำหรับการออกแบบ การนำไปใช้ การทดสอบ และการปรับใช้ Cloud Functions

ความถูกต้อง

ส่วนนี้อธิบายแนวทางปฏิบัติที่ดีที่สุดทั่วไปสำหรับการออกแบบและการใช้งาน Cloud Functions

เขียนฟังก์ชัน idempotent

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

อย่าเริ่มกิจกรรมเบื้องหลัง

กิจกรรมเบื้องหลังคือสิ่งที่เกิดขึ้นหลังจากที่ฟังก์ชันของคุณสิ้นสุดลง การเรียกใช้ฟังก์ชันจะเสร็จสิ้นเมื่อฟังก์ชันส่งคืนหรือส่งสัญญาณว่าเสร็จสิ้น เช่น โดยการ callback อาร์กิวเมนต์การเรียกกลับในฟังก์ชันพื้นหลัง Node.js รหัสใดๆ ที่รันหลังจากการยุติอย่างนุ่มนวลไม่สามารถเข้าถึง CPU และจะไม่คืบหน้าใดๆ

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

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

ลบไฟล์ชั่วคราวเสมอ

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

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

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

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

เครื่องมือ

ส่วนนี้ให้แนวทางเกี่ยวกับวิธีการใช้เครื่องมือในการปรับใช้ ทดสอบ และโต้ตอบกับ Cloud Functions

การพัฒนาท้องถิ่น

การปรับใช้ฟังก์ชันใช้เวลาเล็กน้อย ดังนั้นจึงมักจะเร็วกว่าในการทดสอบโค้ดของฟังก์ชันของคุณในเครื่อง

นักพัฒนา Firebase สามารถใช้ Firebase CLI Cloud Function Emulator

ใช้ Sendgrid เพื่อส่งอีเมล

Cloud Functions ไม่อนุญาตให้มีการเชื่อมต่อขาออกบนพอร์ต 25 ดังนั้นคุณจึงไม่สามารถทำการเชื่อมต่อที่ไม่ปลอดภัยกับเซิร์ฟเวอร์ SMTP วิธีที่แนะนำในการส่งอีเมลคือการใช้ SendGrid คุณสามารถค้นหาตัวเลือกอื่นๆ สำหรับการส่งอีเมลในการ ส่งอีเมลจากบทแนะนำอินสแตนซ์ สำหรับ Google Compute Engine

ประสิทธิภาพ

ส่วนนี้อธิบายแนวทางปฏิบัติที่ดีที่สุดสำหรับการเพิ่มประสิทธิภาพ

ใช้การพึ่งพาอย่างชาญฉลาด

เนื่องจากฟังก์ชันไม่มีสถานะ สภาพแวดล้อมการดำเนินการจึงมักเริ่มต้นจากศูนย์ (ในช่วงที่เรียกว่า cold start ) เมื่อเกิดการเริ่มเย็น บริบทส่วนกลางของฟังก์ชันจะถูกประเมิน

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

ใช้ตัวแปรส่วนกลางเพื่อนำวัตถุกลับมาใช้ใหม่ในการเรียกใช้ในอนาคต

ไม่มีการรับประกันว่าสถานะของ Cloud Function จะได้รับการเก็บรักษาไว้สำหรับการเรียกใช้ในอนาคต อย่างไรก็ตาม Cloud Functions มักจะรีไซเคิลสภาพแวดล้อมการดำเนินการของการเรียกใช้ครั้งก่อน หากคุณประกาศตัวแปรในขอบเขตส่วนกลาง ค่าของตัวแปรนั้นสามารถนำมาใช้ซ้ำในการเรียกใช้ครั้งต่อไปโดยไม่ต้องคำนวณใหม่

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

console.log('Global scope');
const perInstance = heavyComputation();
const functions = require('firebase-functions');

exports.function = functions.https.onRequest((req, res) => {
    console.log('Function invocation');
    const perFunction = lightweightComputation();

    res.send(`Per instance: ${perInstance}, per function: ${perFunction}`);
});

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

ทำการเริ่มต้นขี้เกียจของตัวแปรส่วนกลาง

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

const functions = require('firebase-functions');
let myCostlyVariable;

exports.function = functions.https.onRequest((req, res) => {
    doUsualWork();
    if(unlikelyCondition()){
        myCostlyVariable = myCostlyVariable || buildCostlyVariable();
    }
    res.status(200).send('OK');
});

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

ลดการเริ่มเย็นโดยกำหนดจำนวนอินสแตนซ์ขั้นต่ำ

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

ดู พฤติกรรมการควบคุมมาตราส่วน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกรันไทม์เหล่านี้

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพในวิดีโอ "Google Cloud Performance Atlas" Cloud Functions Cold Boot Time