จัดคิวฟังก์ชันด้วย Cloud Tasks


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

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

เพื่อลดความซับซ้อนนี้ คุณเขียนฟังก์ชันคิวงานที่ตั้งค่าตัวเลือกงานพื้นฐาน เช่น scheduleTime และ dispatchDeadline และส่งฟังก์ชันไปยังคิวใน Cloud Tasks ได้ สภาพแวดล้อม Cloud Tasks ออกแบบมาโดยเฉพาะเพื่อให้มั่นใจได้ว่านโยบายการควบคุมความคับคั่งและการลองใหม่มีประสิทธิภาพสำหรับการดำเนินการเหล่านี้โดยเฉพาะ

Firebase SDK สำหรับ Cloud Functions for Firebase v3.20.1 ขึ้นไปสามารถทำงานร่วมกับ Firebase Admin SDK เวอร์ชัน 10.2.0 ขึ้นไปเพื่อรองรับฟังก์ชันคิวงาน

การใช้ฟังก์ชันคิวงานกับ Firebase อาจทำให้มีค่าใช้จ่ายในการประมวลผล Cloud Tasks โปรดดูข้อมูลเพิ่มเติมที่ราคาของ Cloud Tasks

สร้างฟังก์ชันคิวงาน

หากต้องการใช้ฟังก์ชันคิวงาน ให้ทำตามขั้นตอนต่อไปนี้

  1. เขียนฟังก์ชันคิวงานโดยใช้ Firebase SDK สำหรับ Cloud Functions
  2. ทดสอบฟังก์ชันโดยทริกเกอร์ด้วยคำขอ HTTP
  3. ทำให้ฟังก์ชันใช้งานได้ด้วย Firebase CLI เมื่อทำให้ฟังก์ชันคิวงานใช้งานได้เป็นครั้งแรก CLI จะสร้างคิวงานใน Cloud Tasks พร้อมตัวเลือก (การจำกัดอัตราแล้วลองอีกครั้ง) ที่ระบุไว้ในซอร์สโค้ดของคุณ
  4. เพิ่มงานลงในคิวงานที่สร้างขึ้นใหม่ แล้วส่งต่อพารามิเตอร์เพื่อตั้งค่ากำหนดการดำเนินการ หากจำเป็น โดยการเขียนโค้ดโดยใช้ Admin SDK และทำให้ใช้งานได้ใน Cloud Functions for Firebase

เขียนฟังก์ชันของคิวงาน

ใช้ onDispatch เพื่อเริ่มเขียนฟังก์ชันคิวงาน ส่วนสำคัญของการเขียนฟังก์ชันคิวงานคือการตั้งค่าการทดลองซ้ำต่อคิวและการกำหนดค่าการจำกัดอัตรา ตัวอย่างโค้ดในหน้านี้จะอิงตามแอปที่สร้างบริการซึ่งสำรองข้อมูลรูปภาพทั้งหมดจากภาพดาราศาสตร์ประจำวันของนาซา

กำหนดค่าฟังก์ชันของคิวงาน

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

exports.backupApod = functions
    .runWith( {secrets: ["NASA_API_KEY"]})
    .tasks.taskQueue({
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }).onDispatch(async (data) => {
  • retryConfig.maxAttempts=5: งานแต่ละรายการในคิวงานจะพยายามซ้ำสูงสุด 5 ครั้งโดยอัตโนมัติ วิธีนี้จะช่วยลดข้อผิดพลาดชั่วคราว เช่น ข้อผิดพลาดของเครือข่ายหรือการหยุดชะงักของบริการชั่วคราวของบริการภายนอกที่เกี่ยวข้อง
  • retryConfig.minBackoffSeconds=60: งานแต่ละอย่างจะลองซ้ำอย่างน้อย 60 วินาทีจากความพยายามแต่ละครั้ง วิธีนี้จะช่วยกันบัฟเฟอร์ขนาดใหญ่ระหว่างความพยายามแต่ละครั้ง ดังนั้นเราจึงไม่ต้องเร่งการพยายามลองใหม่ 5 ครั้งให้เร็วเกินไป
  • rateLimits.maxConcurrentDispatch=6: ระบบจะส่งงานไม่เกิน 6 งานในเวลาที่กำหนด วิธีนี้ช่วยให้มั่นใจว่าจะมีคำขอสตรีมไปยังฟังก์ชันที่สำคัญอย่างต่อเนื่อง และช่วยลดจำนวนอินสแตนซ์ที่ใช้งานอยู่และ Cold Start

ทดสอบฟังก์ชันของคิวงาน

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

 # start the Firebase Emulators
 firebase emulators:start

 # trigger the emulated task queue function
 curl \
  -X POST                                            # An HTTP POST request...
  -H "content-type: application/json" \              # ... with a JSON body
  http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
  -d '{"data": { ... some data .... }}'              # ... with JSON encoded data

ทำให้ฟังก์ชันคิวงานใช้งานได้

ทำให้ฟังก์ชันคิวงานใช้งานได้โดยใช้ Firebase CLI:

$ firebase deploy --only functions:backupApod

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

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

จัดคิวงานของฟังก์ชัน

คุณสามารถจัดคิวฟังก์ชันคิวงานใน Cloud Tasks จากสภาพแวดล้อมเซิร์ฟเวอร์ที่เชื่อถือได้ เช่น Cloud Functions for Firebase โดยใช้ Firebase Admin SDK สำหรับ Node.js หากคุณเพิ่งเริ่มใช้ SDK ผู้ดูแลระบบ โปรดดูที่หัวข้อเพิ่ม Firebase ไปยังเซิร์ฟเวอร์เพื่อเริ่มต้นใช้งาน

ในขั้นตอนทั่วไป Admin SDK จะสร้างงานใหม่ จัดคิวงานใน Cloud Tasks และตั้งค่าการกำหนดค่าสำหรับงานดังกล่าว ดังนี้

exports.enqueueBackupTasks = functions.https.onRequest(
async (_request, response) => {
  const queue = getFunctions().taskQueue("backupApod");
  const enqueues = [];
  for (let i = 0; i <= 10; i += 1) {
    // Enqueue each task with i*60 seconds delay. Our task queue function
    // should process ~1 task/min.
    const scheduleDelaySeconds = i * 60 
    enqueues.push(
        queue.enqueue(
          { id: `task-${i}` },
          {
            scheduleDelaySeconds,
            dispatchDeadlineSeconds: 60 * 5 // 5 minutes
          },
        ),
    );
  }
  await Promise.all(enqueues);
  response.sendStatus(200);

});
  • scheduleDelaySeconds: โค้ดตัวอย่างจะพยายามกระจายการดำเนินการของงานด้วยการเชื่อมโยงความล่าช้าเป็นนาทีที่ N สำหรับงานที่ N ซึ่งจะแปลงเป็นการเรียกใช้ประมาณ 1 งาน/นาที โปรดทราบว่าคุณจะใช้ scheduleTime ได้ด้วยหากต้องการให้ Cloud Tasks ทริกเกอร์งานในเวลาที่เฉพาะเจาะจง
  • dispatchDeadlineSeconds: ระยะเวลาสูงสุด ที่ Cloud Tasks จะรอให้งานเสร็จสมบูรณ์ Cloud Tasks จะลองทำงานอีกครั้งหลังจากกำหนดค่าคิวใหม่ หรือจนกว่าจะถึงกำหนดเวลานี้ ในตัวอย่าง คิวได้รับการกำหนดค่าให้ลองทำงานอีกครั้งได้สูงสุด 5 ครั้ง แต่งานจะถูกยกเลิกโดยอัตโนมัติหากกระบวนการทั้งหมด (รวมถึงการพยายามลองใหม่) ใช้เวลานานกว่า 5 นาที

การแก้ปัญหา

เปิดการบันทึก Cloud Tasks

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

สิทธิ์ IAM

คุณอาจเห็นข้อผิดพลาด PERMISSION DENIED รายการเมื่อจัดคิวงานหรือเมื่อ Cloud Tasks พยายามเรียกใช้ฟังก์ชันคิวงาน ตรวจสอบว่าโปรเจ็กต์มีการเชื่อมโยง IAM ต่อไปนี้

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • ข้อมูลประจำตัวที่ใช้กำหนดคิวงานไปยัง Cloud Tasks ต้องมีสิทธิ์ใช้บัญชีบริการที่เชื่อมโยงกับงานใน Cloud Tasks

    ในตัวอย่างนี้คือบัญชีบริการเริ่มต้นของ App Engine

ดูเอกสาร IAM ของ Google Cloud เพื่อดูวิธีเพิ่มบัญชีบริการเริ่มต้นของ App Engine เป็นผู้ใช้บัญชีบริการเริ่มต้นของ App Engine

gcloud functions add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker