จัดคิวฟังก์ชันด้วย 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 v10.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 เพื่อเริ่มต้นเขียนฟังก์ชันคิวงาน ส่วนสําคัญในการเขียนฟังก์ชันคิวงานคือการกําหนดการกําหนดค่าการลองอีกครั้งต่อคิวและการจํากัดอัตรา ตัวอย่างโค้ดในหน้านี้อิงตามแอปที่ตั้งค่าบริการสํารองข้อมูลรูปภาพทั้งหมดจาก Astronomy Picture of the Day ของ NASA

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

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

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

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

ในกรณีส่วนใหญ่ Cloud Functionsโปรแกรมจำลองเป็นวิธีที่ดีที่สุดในการทดสอบฟังก์ชันคิวงาน ดูเอกสารประกอบของ Emulator Suite เพื่อดูวิธีเครื่องมือวัดแอปสำหรับการจําลองฟังก์ชันคิวงาน

นอกจากนี้ ฟังก์ชันคิวงานจะแสดงเป็นฟังก์ชัน HTTP แบบง่ายใน Firebase Local Emulator Suite คุณสามารถทดสอบฟังก์ชันงานจำลองได้โดยส่งคำขอ 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 มีข้อมูลการวินิจฉัยที่เป็นประโยชน์ เช่น สถานะคำขอที่เชื่อมโยงกับงาน โดยค่าเริ่มต้น ระบบจะปิดบันทึกจาก 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