Cloud Tasks (पहली जनरेशन) की मदद से फ़ंक्शन को लाइन में लगाना

टास्क की लाइन में लगाने वाले फ़ंक्शन, Google Cloud Tasks का फ़ायदा उठाते हैं. इससे आपके ऐप्लिकेशन को, ज़्यादा समय लेने वाले, ज़्यादा संसाधनों की ज़रूरत वाले या बैंडविथ की सीमा वाले टास्क को एसिंक्रोनस तरीके से, आपके मुख्य ऐप्लिकेशन फ़्लो से बाहर चलाने में मदद मिलती है.

उदाहरण के लिए, मान लें कि आपको इमेज फ़ाइलों के बड़े सेट का बैकअप बनाना है. ये फ़ाइलें फ़िलहाल, रेट लिमिट वाले एपीआई पर होस्ट की गई हैं. उस एपीआई का ज़िम्मेदारी से इस्तेमाल करने के लिए, आपको उसकी रेट लिमिट का पालन करना होगा. इसके अलावा, लंबे समय तक चलने वाली इस तरह की जॉब, टाइम आउट और मेमोरी की सीमाओं की वजह से फ़ेल हो सकती है.

इस समस्या को कम करने के लिए, टास्क की लाइन में लगाने वाला फ़ंक्शन लिखा जा सकता है. यह फ़ंक्शन, टास्क के बुनियादी विकल्प सेट करता है. जैसे, scheduleTime और dispatchDeadline. इसके बाद, यह फ़ंक्शन Cloud Tasks में लाइन में लगा दिया जाता है. The Cloud Tasks एनवायरमेंट, खास तौर पर इस तरह की कार्रवाइयों के लिए बनाया गया है. इससे, कंजेशन को असरदार तरीके से कंट्रोल किया जा सकता है और फिर से कोशिश करने की नीतियां लागू की जा सकती हैं.

Firebase के लिए Cloud Functions for Firebase का SDK टूल, वर्शन 3.20.1 और इसके बाद के वर्शन, टास्क की लाइन में लगाने वाले फ़ंक्शन के साथ काम करने के लिए, Firebase Admin SDK का SDK टूल, वर्शन 10.2.0 और इसके बाद के वर्शन के साथ इंटरऑपरेट करता है.

Firebase के साथ टास्क की लाइन में लगाने वाले फ़ंक्शन का इस्तेमाल करने पर, Cloud Tasks प्रोसेसिंग के लिए शुल्क लग सकता है. ज़्यादा जानकारी के लिए, Cloud Tasksकी कीमत देखें.

टास्क की लाइन में लगाने वाले फ़ंक्शन बनाना

टास्क की लाइन में लगाने वाले फ़ंक्शन का इस्तेमाल करने के लिए, यह तरीका अपनाएं:

  1. Cloud Functions के लिए Firebase SDK टूल का इस्तेमाल करके, टास्क की लाइन में लगाने वाला फ़ंक्शन लिखें.
  2. एचटीटीपी अनुरोध भेजकर, अपने फ़ंक्शन को ट्रिगर करके उसकी जांच करें.
  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: टास्क की लाइन में मौजूद हर टास्क के लिए, पांच बार तक अपने-आप फिर से कोशिश की जाती है. इससे, नेटवर्क की गड़बड़ियों या किसी बाहरी सेवा में अस्थायी तौर पर होने वाली रुकावट जैसी अस्थायी गड़बड़ियों को कम करने में मदद मिलती है.
  • retryConfig.minBackoffSeconds=60: हर टास्क के लिए, हर कोशिश के बाद कम से कम 60 सेकंड के बाद फिर से कोशिश की जाती है. इससे, हर कोशिश के बीच ज़्यादा समय मिलता है. इसलिए, पांच बार फिर से कोशिश करने की सीमा को बहुत जल्दी खत्म नहीं किया जाता.
  • rateLimits.maxConcurrentDispatch=6: किसी भी समय, ज़्यादा से ज़्यादा छह टास्क भेजे जा सकते हैं. इससे, मुख्य फ़ंक्शन को अनुरोधों की एक स्थिर स्ट्रीम मिलती है. साथ ही, चालू इंस्टेंस और कोल्ड स्टार्ट की संख्या कम करने में मदद मिलती है.

टास्क की लाइन में लगाने वाले फ़ंक्शन की जांच करना

ज़्यादातर मामलों में, Cloud Functions एम्युलेटर, टास्क की लाइन में लगाने वाले फ़ंक्शन की जांच करने का सबसे अच्छा तरीका है. टास्क की लाइन में लगाने वाले फ़ंक्शन के एम्युलेशन के लिए, अपने ऐप्लिकेशन को इंस्ट्रुमेंट करने का तरीका जानने के लिए, Emulator Suite का दस्तावेज़ देखें.

इसके अलावा, टास्क की लाइन में लगाने वाले फ़ंक्शन, Firebase Local Emulator Suite में सामान्य एचटीटीपी फ़ंक्शन के तौर पर दिखाए जाते हैं. एम्युलेट किए गए टास्क फ़ंक्शन की जांच करने के लिए, JSON डेटा पेलोड के साथ एचटीटीपी POST अनुरोध भेजा जा सकता है:

 # 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 for 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 मिनट की देरी को जोड़ा जाता है. इसका मतलब है कि हर मिनट में ~ एक टास्क ट्रिगर किया जाता है. ध्यान दें कि अगर आपको Cloud Tasks से टास्क ट्रिगर कराना है, तो scheduleTime का भी इस्तेमाल किया जा सकता है.
  • dispatchDeadlineSeconds: ज़्यादा से ज़्यादा इतना समय Cloud Tasks इंतज़ार करेगा जब तक टास्क पूरा न हो जाए. Cloud Tasks लाइन के फिर से कोशिश करने के कॉन्फ़िगरेशन के मुताबिक, टास्क के लिए फिर से कोशिश करेगा. यह तब तक जारी रहेगा, जब तक यह समयसीमा खत्म नहीं हो जाती. सैंपल में, लाइन को पांच बार तक टास्क के लिए फिर से कोशिश करने के लिए कॉन्फ़िगर किया गया है. हालांकि, अगर पूरी प्रोसेस (फिर से कोशिश करने की कोशिशों के साथ) में पांच मिनट से ज़्यादा समय लगता है, तो टास्क अपने-आप रद्द हो जाता है.

समस्या का हल

Cloud Tasks की लॉगिंग चालू करना

Cloud Tasks के लॉग में, काम की डायग्नोस्टिक जानकारी शामिल होती है. जैसे, किसी टास्क से जुड़े अनुरोध की स्थिति. डिफ़ॉल्ट रूप से, Cloud Tasks के लॉग बंद होते हैं. इसकी वजह यह है कि आपके प्रोजेक्ट पर, Cloud Tasks के लॉग की संख्या बहुत ज़्यादा हो सकती है. हमारा सुझाव है कि टास्क की लाइन में लगाने वाले फ़ंक्शन को डेवलप और डीबग करते समय, डीबग लॉग चालू करें. लॉगिंग चालू करना देखें.

IAM की अनुमतियां

टास्क को लाइन में लगाते समय या Cloud Tasks के टास्क की लाइन में लगाने वाले फ़ंक्शन को कॉल करने की कोशिश करते समय, आपको PERMISSION DENIED गड़बड़ियां दिख सकती हैं. पक्का करें कि आपके प्रोजेक्ट में, IAM की ये बाइंडिंग मौजूद हों:

  • Cloud Tasks में टास्क को लाइन में लगाने के लिए इस्तेमाल की जाने वाली आइडेंटिटी के पास, Cloud Tasks की IAM अनुमति होनी चाहिए.cloudtasks.tasks.create

    सैंपल में, यह App Engine डिफ़ॉल्ट सेवा खाता है

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 डिफ़ॉल्ट सेवा खाते के उपयोगकर्ता के तौर पर जोड़ने के तरीके के बारे में निर्देश देखें.

  • टास्क की लाइन में लगाने वाले फ़ंक्शन को ट्रिगर करने के लिए इस्तेमाल की जाने वाली आइडेंटिटी के पास, cloudfunctions.functions.invoke अनुमति होनी चाहिए.

    सैंपल में, यह App Engine डिफ़ॉल्ट सेवा खाता है

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