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


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

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

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

Firebase SDK สำหรับฟังก์ชันระบบคลาวด์สำหรับ 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 หากยังไม่คุ้นเคยกับ Admin 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 เริ่มต้น

โปรดดูเอกสารประกอบ Google Cloud IAM เกี่ยวกับวิธีการเพิ่มบัญชีบริการเริ่มต้นของ 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