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

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

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

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

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

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

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

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

  1. Cloud Functions के लिए Firebase SDK का इस्तेमाल करके, टास्क की लाइन में लगाने वाला फ़ंक्शन लिखें.
  2. एचटीटीपी अनुरोध भेजकर, अपने फ़ंक्शन की जांच करें.
  3. Firebase 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

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

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

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

Firebase के लिए Cloud Functions जैसे भरोसेमंद सर्वर एनवायरमेंट से, Cloud Tasks में टास्क की लाइन में लगाने वाले फ़ंक्शन को लाइन में लगाया जा सकता है. इसके लिए, Firebase Admin SDK for Node.js का इस्तेमाल किया जाता है.Cloud Functions for Firebase अगर 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 के लॉग बंद होते हैं. इसकी वजह यह है कि यह आपके प्रोजेक्ट पर बड़ी संख्या में लॉग जनरेट कर सकता है. हमारा सुझाव है कि टास्क की लाइन में लगाने वाले फ़ंक्शन को डेवलप और डीबग करते समय, डीबग लॉग चालू करें. लॉगिंग चालू करना लेख देखें.

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