העברת תורים של דחיפת הודעות ל-Cloud Tasks‏ (Java)

בדף הזה מוסבר איך אפשר להעביר קוד של תור לדחיפת הודעות מ-Task Queues ל-Cloud Tasks. ‫Cloud Tasks היא עכשיו הדרך המומלצת לעבודה עם תורי דחיפה ב-App Engine.

כשמשתמשים ב-Cloud Tasks, ניגשים לאותו שירות שאליו ניגשים באמצעות Task Queues RPC API. כלומר, לא צריך ליצור מחדש את תורי הדחיפה הקיימים ואת משימות הדחיפה. עם זאת, כדי להשתמש ב-Cloud Tasks API, צריך להעביר קוד שיוצר תורי דחיפה או משימות דחיפה או מבצע אינטראקציה איתם.

אפשר ליצור תורים של משימות מסוג push ומשימות מסוג push ולבצע איתם אינטראקציה באמצעות ממשקי ה-API ל-REST ול-RPC של Cloud Tasks, ספריית הלקוח של Cloud Tasks,‏ Google Cloud CLI ומסוףGoogle Cloud . בדף הזה מופיעות דוגמאות לשימוש ב-CLI של gcloud ובספריית הלקוח של Cloud Tasks.

ב-Cloud Tasks, כל התורים פועלים כתורי push. בהמשך המדריך הזה ובמסמכי Cloud Tasks, המונח תור זהה למונח תור דחיפה (push queue). באופן דומה, המונח משימה שווה ערך למונח משימת push.

תכונות שלא זמינות ב-Cloud Tasks

התכונות הבאות לא זמינות ב-Cloud Tasks:

  • הוספת משימות לתור בעסקאות ב-Datastore
  • שימוש בספריית המשימות שמושהות במקום בשירות worker
  • עבודה עם משימות באפליקציות לפי עקרון ה-Multi-tenancy
  • סימולציה באמצעות שרת הפיתוח המקומי
  • הוספת משימות באופן אסינכרוני

תמחור ומכסות

העברת תורי הדחיפה ל-Cloud Tasks עשויה להשפיע על התמחור והמכסות של האפליקציה.

תמחור

ל-Cloud Tasks יש תמחור משלו. כמו בתורי משימות, שליחת בקשות לאפליקציית App Engine עם משימה עלולה לגרום לאפליקציה לצבור עלויות.

מכסות

המכסות של Cloud Tasks שונות מהמכסות של תורי משימות. בדומה לתורי משימות, שליחת בקשות לאפליקציית App Engine מ-Cloud Tasks עשויה להשפיע על מכסות הבקשות של App Engine.

לפני ההעברה

בקטעים הבאים מפורטים שלבי ההגדרה לפני העברת תורי הדחיפה ל-Cloud Tasks.

העברת תורים לשליפת הודעות

לפני שמתחילים, צריך להעביר תורים של בקשות משיכה לפני שמבצעים את ההוראות במדריך הזה להעברת תורים של בקשות דחיפה. לא מומלץ להעביר תורים של משיכות אחרי העברה של תורים של דחיפות, כי סביר להניח שהשימוש הנדרש בקובץ queue.yaml יגרום להתנהגות לא צפויה ב-Cloud Tasks.

הגנה על הגדרות התור

אחרי שמתחילים את תהליך ההעברה ל-Cloud Tasks, שינוי הקובץ queue.yaml עלול לגרום להתנהגות לא צפויה ולא מומלץ. כדי להגן על הגדרות התור מפני שינויים בקובץ queue.yaml, מבצעים את השלבים הבאים.

  1. מגדירים את ה-CLI של gcloud כך שקובץ queue.yaml לא ייכלל בהמשך הפריסות.

    מוסיפים את קובץ queue.yaml לקובץ .gcloudignore. כדי לבדוק אם כבר יש לכם קובץ .gcloudignore, אתם יכולים להריץ את הפקודה הבאה בטרמינל מהספרייה ברמה העליונה של האפליקציה. הפקודה הזו תציג את שם הקובץ אם הוא קיים.

    ls -a | grep .gcloudignore

    מידע נוסף על קובצי .gcloudignore זמין במאמר בנושא .gcloudignore קובצי עזר.

  2. מגבילים את ההרשאות בקובץ queue.yaml.

    מומלץ לפעול לפי השיטות המומלצות שמתוארות במדריך שלנו בנושא הגדרת אבטחה לתור.

  3. מידע על Cloud Tasks ועל קובץ queue.yaml (אופציונלי).

    כשמשתמשים ב-Cloud Tasks API כדי לנהל את הגדרות התור, פריסת קובץ queue.yaml מבטלת את ההגדרות שנקבעו על ידי Cloud Tasks, וזה עלול לגרום להתנהגות לא צפויה. מומלץ לקרוא את המאמר שימוש בניהול תורים לעומת שימוש בקובץ queue.yaml כדי לקבל מידע נוסף.

הפעלת Cloud Tasks API

כדי להפעיל את Cloud Tasks API, לוחצים על Enable ב-Cloud Tasks API בספריית ה-API. אם במקום הלחצן Enable מופיע הלחצן Manage, סימן שהפעלתם בעבר את Cloud Tasks API בפרויקט ואין צורך להפעיל אותו שוב.

אימות האפליקציה ב-Cloud Tasks API

צריך לאמת את האפליקציה ב-Cloud Tasks API. בקטע הזה נדון באימות בשני תרחישי שימוש שונים.

כדי לפתח או לבדוק את האפליקציה באופן מקומי, מומלץ להשתמש בחשבון שירות. הוראות להגדרת חשבון שירות ולחיבור שלו לאפליקציה מופיעות במאמר קבלת פרטי כניסה לחשבון שירות וצירופם באופן ידני.

כדי לפרוס את האפליקציה ב-App Engine, לא צריך לספק אימות חדש. פרטי האימות של אפליקציות App Engine מוסקים מ-Application Default Credentials‏ (ADC).

הורדת ה-CLI של gcloud

הורידו והתקינו את ה-CLI של gcloud כדי להשתמש בו עם Cloud Tasks API אם לא התקנתם אותו בעבר. אם כבר התקנתם את ה-CLI של gcloud, מריצים את הפקודה הבאה מהטרמינל.

gcloud components update

ייבוא ספריות לקוח של Cloud

כדי להשתמש בספריית הלקוח של Cloud Tasks באפליקציית App Engine:

  1. מציינים את התלות בספריית הלקוח של Cloud Tasks בקובץ pom.xml:

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
      <version>1.3.0</version>
    </dependency>
  2. מייבאים את התלויות של ספריית הלקוח של Cloud Tasks בקבצים שאחראים ליצירה ולהוספה לתור של המשימות:

    import com.google.cloud.tasks.v2.AppEngineHttpRequest;
    import com.google.cloud.tasks.v2.CloudTasksClient;
    import com.google.cloud.tasks.v2.HttpMethod;
    import com.google.cloud.tasks.v2.QueueName;
    import com.google.cloud.tasks.v2.Task;

יצירה וניהול של תורים

בקטע הזה מוסבר איך ליצור ולנהל תורים באמצעות Cloud Tasks API.

ב-Cloud Tasks, לא משתמשים בקובץ queue.yaml כדי ליצור תורים או לנהל אותם. במקום זאת, משתמשים ב-Cloud Tasks API. לא מומלץ להשתמש גם בקובץ queue.yaml וגם ב-Cloud Tasks API, אבל יכול להיות שזה יהיה חלק בלתי נמנע מהמעבר מ-Task Queues ל-Cloud Tasks, בהתאם לאפליקציה שלכם. כדאי לקרוא את המאמר שימוש בניהול תורים לעומת queue.yaml כדי ללמוד על שיטות מומלצות.

יצירת תורים

כדאי לקרוא את הקטע הזה אם האפליקציה שלכם יוצרת תורים באופן פרוגרמטי, או אם אתם רוצים ליצור תורים נוספים משורת הפקודה.

ב-Cloud Tasks, שמות התורים הם מהצורה projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID. החלק LOCATION_ID בשם התור תואם ל Google Cloud אזור. החלק QUEUE_ID בשם התור שווה לשדה name של התור ב-Task Queues. שם התור נוצר במהלך יצירת התור על סמך הפרויקט, האזור והערך QUEUE_ID שאתם מציינים.

באופן כללי, המיקום של התור (כלומר, האזור) צריך להיות זהה לאזור של האפליקציה. יש שני חריגים לכלל הזה: אפליקציות שמשתמשות באזור europe-west ואפליקציות שמשתמשות באזור us-central. ב-Cloud Tasks, האזורים האלה נקראים europe-west1 ו-us-central1 בהתאמה.

אפשר להגדיר את התור במהלך היצירה שלו, אבל אפשר גם לעדכן אותו אחרי שהוא נוצר.

אין צורך ליצור מחדש תורים קיימים. במקום זאת, אפשר להעביר את הקוד שפועל באינטראקציה עם התורים הקיימים על ידי קריאת החלקים הרלוונטיים במדריך הזה.

שימוש חוזר בשמות של תורים

צריך להמתין 7 ימים אחרי מחיקת תור כדי ליצור תור עם אותו מזהה תור באותו פרויקט ובאותו מיקום (כלומר, באותו אזור).

בדוגמה הבאה נוצרות שתי תורים באמצעות Cloud Tasks. לרשימת ההמתנה הראשונה יש מזהה רשימת המתנה queue-blue, והיא מוגדרת לשליחת כל המשימות לגרסה v2 של השירות task-module בקצב של 5/s. לתור השני יש מזהה תור queue-red והוא משבץ משימות בקצב של 1/s. שניהם נוצרים בפרויקט עם מזהה הפרויקט your-project-id במיקום us-central1. זהו המקבילה ב-Cloud Tasks ליצירת תורים ב-Task Queues.

gcloud

ה-CLI של gcloud מסיק את הפרויקט והמיקום מההגדרה של ה-CLI של gcloud.

gcloud tasks queues create queue-blue \
--max-dispatches-per-second=5 \
--routing-override=service:task-module,version:v2
gcloud tasks queues create queue-red \
--max-dispatches-per-second=1

ספריית לקוח

import com.google.cloud.tasks.v2.AppEngineRouting;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;

public class CreateQueue {
  public static void createQueue(
      String projectId, String locationId, String queueBlueName, String queueRedName)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueBlueName = "queue-blue";
      // String queueRedName = "queue-red";

      LocationName parent = LocationName.of(projectId, locationId);

      Queue queueBlue =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueBlueName).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(5.0))
              .setAppEngineRoutingOverride(
                  AppEngineRouting.newBuilder().setVersion("v2").setService("task-module"))
              .build();

      Queue queueRed =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueRedName).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .build();

      Queue[] queues = new Queue[] {queueBlue, queueRed};
      for (Queue queue : queues) {
        Queue response = client.createQueue(parent, queue);
        System.out.println(response);
      }
    }
  }
}

מידע נוסף זמין במאמר בנושא יצירת תור של Cloud Tasks.

הגדרת קצב העיבוד של התור

בטבלה הבאה מפורטים השדות ששונים בין Task Queues לבין Cloud Tasks.

השדה Task Queues שדה Cloud Tasks תיאור
rate max_dispatches_per_second הקצב המקסימלי שבו המשימות מוקצות מהתור
max_concurrent_requests max_concurrent_dispatches המספר המקסימלי של משימות מקבילות שאפשר לשלוח מהתור
bucket_size max_burst_size

‫Cloud Tasks מחשב מאפיין לקריאה בלבד max_burst_size שמגביל את מהירות העיבוד של משימות בתור על סמך הערך של max_dispatches_per_second. השדה הזה מאפשר לתור להגיע לקצב גבוה כדי שהעיבוד יתחיל זמן קצר אחרי שהמשימה תתווסף לתור, אבל עדיין מגביל את השימוש במשאבים כשמתווספות לתור הרבה משימות בפרק זמן קצר.

בתורים של App Engine שנוצרו או עודכנו באמצעות קובץ queue.xml/yaml, הערך של max_burst_size שווה בהתחלה לערך של bucket_size. עם זאת, אם התור יועבר בהמשך לפקודה update באמצעות ממשק Cloud Tasks כלשהו, הערך של max_burst_size יתאפס על סמך הערך של max_dispatches_per_second, בלי קשר לעדכון של max_dispatches_per_second.

total_storage_limit הוצא משימוש ב-Cloud Tasks ב-Cloud Tasks אין תמיכה בהגדרת מגבלת אחסון מותאמת אישית

אפשר להגדיר את קצב העיבוד של התור כשיוצרים את התור או כשמעדכנים אותו לאחר מכן. בדוגמה הבאה נעשה שימוש ב-Cloud Tasks כדי להגדיר את קצב העיבוד בתור בשם queue-blue שכבר נוצר. אם התור queue-blue נוצר או הוגדר באמצעות קובץ queue.yaml, הדוגמה הבאה מאפסת את max_burst_size על סמך הערך max_dispatches_per_second של 20. זוהי הפעולה המקבילה ב-Cloud Tasks להגדרת קצב העיבוד של התור ב-Task Queues.

gcloud

gcloud tasks queues update queue-blue \
--max-dispatches-per-second=20 \
--max-concurrent-dispatches=10

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;
import com.google.cloud.tasks.v2.UpdateQueueRequest;

public class UpdateQueue {
  public static void updateQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "queue-blue";

      LocationName parent = LocationName.of(projectId, locationId);

      Queue queueBlue =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, queueId).toString())
              .setRateLimits(
                  RateLimits.newBuilder()
                      .setMaxDispatchesPerSecond(20.0)
                      .setMaxConcurrentDispatches(10))
              .build();

      UpdateQueueRequest request = UpdateQueueRequest.newBuilder().setQueue(queueBlue).build();

      Queue response = client.updateQueue(request);
      System.out.println(response);
    }
  }
}

מידע נוסף זמין במאמר הגדרת מגבלות קצב.

השבתה והפעלה מחדש של תורים

ב-Cloud Tasks, המונח השהיה משמש באותו אופן שבו המונח השבתה משמש ב-Task Queues. השהיה של תור מפסיקה את הביצוע של המשימות בתור עד להמשך הפעולה של התור. עם זאת, אפשר להמשיך להוסיף משימות לתור שהושהה. ב-Cloud Tasks, המונח המשך משמש באותו אופן שבו הוא משמש ב-Task Queues.

בדוגמה הבאה מושהית תור עם מזהה התור queueName . הפעולה הזו מקבילה להשבתה של תורים ב-Task Queues.

gcloud

gcloud tasks queues pause 

queueName

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class PauseQueue {
  public static void pauseQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.pauseQueue(queueName);
      System.out.println("Queue Paused.");
    }
  }
}

מידע נוסף זמין במאמר בנושא Cloud Tasks, בקטע השהיית תורים.

מחיקת תורים

אחרי שמוחקים תור, צריך לחכות 7 ימים לפני שיוצרים תור עם אותו שם. אם אתם לא יכולים לחכות 7 ימים, כדאי למחוק את כל המשימות מהתור ולהגדיר מחדש את התור.

בדוגמה הבאה נמחקת התור עם מזהה התור foo . זהו המקבילה ב-Cloud Tasks למחיקת תורים ב-Task Queues.

gcloud

gcloud tasks queues delete 

foo

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class DeleteQueue {
  public static void deleteQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.deleteQueue(queueName);
      System.out.println("Queue Deleted.");
    }
  }
}

מידע נוסף זמין במאמר בנושא Cloud Tasks מחיקת תורים.

יצירה וניהול של משימות

בקטע הזה מוסבר איך ליצור משימות ולנהל אותן באמצעות Cloud Tasks API.

יצירת משימות

בטבלה הבאה מפורטים השדות ששונים בין Task Queues לבין Cloud Tasks.

השדה Task Queues שדה Cloud Tasks תיאור
מה חדש ב-Cloud Tasks app_engine_http_request יוצר בקשה שמיועדת לשירות App Engine. המשימות האלה נקראות משימות של App Engine.
method http_method מציינת את שיטת הבקשה, לדוגמה, POST
url relative_uri מציין את המטפל במשימה. שימו לב להבדל באות האחרונה: i במזהה משאבים אחיד במקום l במען משאבים אחיד
target app_engine_routing זה שינוי אופציונלי. מציינים את service, version ו-instance של App Engine למשימה של App Engine. אם לא מגדירים את המאפיין, המערכת משתמשת בגרסה, במופע ובשירות שמוגדרים כברירת מחדל.

בדוגמה הבאה נוצרת משימה שמופנית אל ה-handler‏ /worker בשירות ברירת המחדל של App Engine. זהו המקבילה ב-Cloud Tasks ליצירת משימות בתורי משימות.

gcloud

gcloud tasks create-app-engine-task --queue=default \
--method=POST --relative-uri=/worker?key=key

ספריית לקוח

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.nio.charset.Charset;

public class CreateTask {
  public static void createTask(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      String key = "key";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task taskParam =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker?key=" + key)
                      .setHttpMethod(HttpMethod.GET)
                      .build())
              .build();

      Task taskPayload =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(key, Charset.defaultCharset()))
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Send create task request.
      Task[] tasks = new Task[] {taskParam, taskPayload};
      for (Task task : tasks) {
        Task response = client.createTask(queueName, task);
        System.out.println(response);
      }
    }
  }
}

מידע נוסף זמין במאמר בנושא יצירת משימות App Engine במאמרי העזרה של Cloud Tasks.

ציון שירות היעד והניתוב

הגדרת שירות היעד, הגרסה והמופע של App Engine למשימות של App Engine היא אופציונלית. כברירת מחדל, משימות של App Engine מנותבות לשירות, לגרסה ולמופע שמוגדרים כברירת מחדל בזמן הניסיון לבצע את המשימה.

מגדירים את מאפיין app_engine_routing של המשימה במהלך יצירת המשימה כדי לציין שירות, גרסה או מופע אחרים של App Engine למשימה.

כדי להפנות את כל המשימות בתור מסוים לאותו שירות, גרסה ומופע של App Engine, אפשר להגדיר את המאפיין app_engine_routing_override בתור.

מידע נוסף זמין במאמר בנושא הגדרת ניתוב.

העברת נתונים אל ה-handler

בדומה לתורי משימות, אפשר להעביר נתונים ל-handler בשתי דרכים באמצעות Cloud Tasks. אפשר להעביר נתונים כפרמטרים של שאילתה ב-URI היחסי, או להעביר נתונים בגוף הבקשה באמצעות שיטות HTTP‏ POST או PUT.

ב-Cloud Tasks, המונח body משמש באותו אופן שבו המונח payload משמש ב-Task Queues. ב-Cloud Tasks, סוג התוכן של ה-body שמוגדר כברירת מחדל הוא octet-stream ולא טקסט פשוט. אפשר להגדיר את סוג התוכן של ה-body על ידי ציון שלו בכותרת.

בדוגמה הבאה מועבר מפתח ל-handler‏ /worker בשתי דרכים שונות. זהו המקבילה ב-Cloud Tasks להעברת נתונים ל-handler בתורי משימות.

console

gcloud tasks create-app-engine-task --queue=default --method=GET  \
--relative-uri=

/worker

?key=blue --routing=service:worker
gcloud tasks create-app-engine-task --queue=default --method=POST \
--relative-uri=

/worker

 --routing=service:worker \
--body-content="{'key': 'blue'}"

ספריית לקוח

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.nio.charset.Charset;

public class CreateTask {
  public static void createTask(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      String key = "key";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task taskParam =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker?key=" + key)
                      .setHttpMethod(HttpMethod.GET)
                      .build())
              .build();

      Task taskPayload =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(key, Charset.defaultCharset()))
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Send create task request.
      Task[] tasks = new Task[] {taskParam, taskPayload};
      for (Task task : tasks) {
        Task response = client.createTask(queueName, task);
        System.out.println(response);
      }
    }
  }
}

מתן שמות למשימות

ציון שם המשימה הוא אופציונלי. אם לא מציינים את שם המשימה, Cloud Tasks יוצר אותו בשבילכם על ידי יצירת מזהה משימה והסקת הפרויקט והמיקום (כלומר, האזור) על סמך התור שציינתם במהלך יצירת המשימה.

שמות המשימות הם מהצורה projects/PROJECT_ID/locations/LOCATION_ID/queues/QUEUE_ID/tasks/TASK_ID. החלק TASK_ID בשם המשימה שווה לערך בשדה name של המשימה בתורי המשימות.

שימוש חוזר בשמות של משימות

צריך לחכות לפני שמשתמשים שוב בשם של משימה. משך הזמן שצריך לחכות תלוי בשאלה אם התור ששולח את המשימה נוצר ב-Cloud Tasks או ב-Task Queues.

לגבי משימות בתורים שנוצרו באמצעות Task Queues (כולל תור ברירת המחדל), צריך להמתין כ-9 ימים אחרי שהמשימה המקורית נמחקה או בוצעה. לגבי משימות בתורים שנוצרו באמצעות Cloud Tasks, צריך להמתין כשעה אחרי שהמשימה המקורית נמחקה או בוצעה.

בדוגמה הבאה נוצרת משימה עם הערך TASK_ID שמוגדר ל-first-try, והיא מתווספת לתור ברירת המחדל. זהו המקבילה ב-Cloud Tasks למתן שמות למשימות ב-Task Queues.

gcloud

ה-CLI של gcloud יוצר את שם המשימה על ידי הסקת הפרויקט והמיקום מההגדרה.

gcloud tasks create-app-engine-task first-try --queue=default \
--method=GET --relative-uri=

/worker

ספריית לקוח

כשמשתמשים בספריית הלקוח, צריך לציין את שם המשימה המלא אם רוצים לציין את TASK_ID. הפרויקט והמיקום צריכים להיות זהים לפרויקט ולמיקום של התור שאליו המשימה מתווספת.

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.cloud.tasks.v2.TaskName;

public class CreateTaskWithName {
  public static void createTaskWithName(
      String projectId, String locationId, String queueId, String taskId) throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "default";
      // String taskId = "first-try"

      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      Task.Builder taskBuilder =
          Task.newBuilder()
              .setName(TaskName.of(projectId, locationId, queueId, taskId).toString())
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/worker")
                      .setHttpMethod(HttpMethod.GET)
                      .build());

      // Send create task request.
      Task response = client.createTask(queueName, taskBuilder.build());
      System.out.println(response);
    }
  }
}

ניסיון חוזר של משימות שנכשלו

אפשר להגדיר את ניסיון החוזר של משימות בתורים במהלך יצירת התור, או על ידי עדכון התור. בטבלה הבאה מפורטים השדה Task Queues והשדה התואם ב-Cloud Tasks.

השדה Task Queues שדה Cloud Tasks
task_retry_limit max_attempts
task_age_limit max_retry_duration
min_backoff_seconds min_backoff
max_backoff_seconds max_backoff
max_doublings max_doublings

פרמטרים של ניסיון חוזר ספציפי למשימה

פרמטרים של ניסיון חוזר ספציפיים למשימה שהוגדרו בתורי משימות פועלים ב-Cloud Tasks, אבל אי אפשר לערוך אותם או להגדיר אותם במשימות חדשות. כדי לשנות את פרמטרים הניסיון החוזר למשימה שיש לה פרמטרים של ניסיון חוזר ספציפיים למשימה, צריך ליצור מחדש את המשימה עם תור של Cloud Tasks שיש לו את פרמטרים הניסיון החוזר הרצויים.

בדוגמה הבאה מוצגים תרחישי ניסיון חוזר שונים:

  • ב-fooqueue, המערכת מנסה לבצע מחדש משימות עד שבע פעמים, למשך עד יומיים מניסיון ההפעלה הראשון. אחרי שמגיעים לשתי המגבלות, הפעולה נכשלת באופן סופי.
  • ב-barqueue,‏ App Engine מנסה לבצע מחדש משימות, ומגדיל את המרווח בין כל ניסיון חוזר באופן לינארי עד שמגיעים להשהיה המקסימלית לפני ניסיון חוזר, ואז מנסה שוב ללא הגבלה במרווח המקסימלי (כך שהמרווחים בין הבקשות הם 10 שניות, 20 שניות, 30 שניות וכו', עד 190 שניות, 200 שניות, 200 שניות וכו').
  • בדוגמה bazqueue, מרווח הזמן בין הניסיונות החוזרים מתחיל ב-10 שניות, מוכפל שלוש פעמים, ואז גדל באופן לינארי. לבסוף, המערכת מנסה שוב ושוב ללא הגבלה במרווח המקסימלי (כך שמרווחי הזמן בין הבקשות הם 10 שניות, 20 שניות, 40 שניות, 80 שניות, 160 שניות, 240 שניות, 300 שניות, 300 שניות וכן הלאה).

זהו המקבילה ב-Cloud Tasks לניסיון חוזר של משימות ב-Task Queues.

gcloud

כשמגדירים אפשרויות שמציינות מספר שניות, צריך לכלול s אחרי המספר השלם (למשל 200s ולא 200).

gcloud tasks queues create fooqueue \
--max-attempts=7 \
--max-retry-duration=172800s  #2*60*60*24 seconds in 2 days
gcloud tasks queues create barqueue \
--min-backoff=10s \
--max-backoff=200s \
--max-doublings=0
gcloud tasks queues create bazqueue \
--min-backoff=10s \
--max-backoff=300s \
--max-doublings=3

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.LocationName;
import com.google.cloud.tasks.v2.Queue;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.RateLimits;
import com.google.cloud.tasks.v2.RetryConfig;
import com.google.protobuf.Duration;

public class RetryTask {
  public static void retryTask(
      String projectId, String locationId, String fooqueue, String barqueue, String bazqueue)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String fooqueue = "fooqueue";
      // String barqueue = "barqueue";
      // String bazqueue = "bazqueue";

      LocationName parent = LocationName.of(projectId, locationId);

      Duration retryDuration = Duration.newBuilder().setSeconds(2 * 60 * 60 * 24).build();
      Duration min = Duration.newBuilder().setSeconds(10).build();
      Duration max1 = Duration.newBuilder().setSeconds(200).build();
      Duration max2 = Duration.newBuilder().setSeconds(300).build();

      Queue foo =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, fooqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder().setMaxAttempts(7).setMaxRetryDuration(retryDuration))
              .build();

      Queue bar =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, barqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder()
                      .setMinBackoff(min)
                      .setMaxBackoff(max1)
                      .setMaxDoublings(0))
              .build();

      Queue baz =
          Queue.newBuilder()
              .setName(QueueName.of(projectId, locationId, bazqueue).toString())
              .setRateLimits(RateLimits.newBuilder().setMaxDispatchesPerSecond(1.0))
              .setRetryConfig(
                  RetryConfig.newBuilder()
                      .setMinBackoff(min)
                      .setMaxBackoff(max2)
                      .setMaxDoublings(3))
              .build();

      Queue[] queues = new Queue[] {foo, bar, baz};
      for (Queue queue : queues) {
        Queue response = client.createQueue(parent, queue);
        System.out.println(response);
      }
    }
  }
}

מידע נוסף זמין במאמר בנושא Cloud Tasks הגדרת פרמטרים של ניסיון חוזר.

מחיקת משימות מהתור

כשמוחקים משימה, צריך להמתין 9 ימים לפני שיוצרים משימה עם אותו שם אם המשימה הייתה בתור שנוצר באמצעות קובץ queue.yaml, או שעה אחת אם המשימה הייתה בתור שנוצר באמצעות Cloud Tasks.

בדוגמה הבאה נמחקת המשימה עם מזהה המשימה foo מהתור עם מזהה התור queue1. זהו המקבילה ב-Cloud Tasks למחיקת משימות בתורי משימות.

gcloud

הפרויקט והמיקום של המשימה נגזרים מפרויקט ברירת המחדל של ה-CLI של gcloud.

gcloud tasks delete foo --queue=queue1

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.TaskName;

public class DeleteTask {
  public static void deleteTask(String projectId, String locationId, String queueId, String taskId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "queue1";
      // String taskId = "foo";

      // Construct the fully qualified queue name.
      String taskName = TaskName.of(projectId, locationId, queueId, taskId).toString();

      client.deleteTask(taskName);
      System.out.println("Task Deleted.");
    }
  }
}

מידע נוסף זמין במאמר בנושא Cloud Tasks מחיקת משימה מתור.

מחיקת משימות

בדוגמה הבאה, כל המשימות בתור עם מזהה התור foo נמחקות. זהו המקבילה ב-Cloud Tasks לניקוי משימות ב-Task Queues.

gcloud

הפרויקט והמיקום של התור נגזרים מפרויקט ברירת המחדל של ה-CLI של gcloud.

gcloud tasks queues purge 

foo

ספריית לקוח

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.QueueName;

public class PurgeQueue {
  public static void purgeQueue(String projectId, String locationId, String queueId)
      throws Exception {
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // TODO(developer): Uncomment these lines and replace with your values.
      // String projectId = "your-project-id";
      // String locationId = "us-central1";
      // String queueId = "foo";

      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, queueId).toString();

      client.purgeQueue(queueName);
      System.out.println("Queue Purged.");
    }
  }
}

מידע נוסף זמין במאמר בנושא מחיקת כל המשימות מתור בתיעוד של Cloud Tasks.

דוגמה ל-Cloud Tasks ב-Java 8

הדוגמה הבאה היא הגדרה בסיסית ליצירת תור ולהוספת משימה לתור באמצעות Cloud Tasks. בדוגמה הזו מניחים שהמפתח יצר קובץ pom.xml כדי לציין את התלות ב-Cloud Tasks, כפי שמתואר בקטע ייבוא ספריית הלקוח. זוהי הדוגמה המקבילה ב-Cloud Tasks לדוגמה של תור משימות ב-Java 8 ב-Task Queues.

הקובץ שאחראי ליצירת המשימה ולהוספה שלה לתור יוצר משימה ומוסיף אותה לתור ברירת המחדל באמצעות ספריית הלקוח של Cloud Tasks:

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(
    name = "TaskEnqueue",
    description = "Enqueue a task targeted at endpoint '/cloudtasks/worker'",
    urlPatterns = "/cloudtasks/enqueue")
public class Enqueue extends HttpServlet {

  // TODO(developer): Replace these variables before running the sample.
  static final String projectId = "my-project-id";
  static final String locationId = "us-central1";

  // Function creates Cloud Tasks from form submissions.
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String key = request.getParameter("key");

    try (CloudTasksClient client = CloudTasksClient.create()) {
      // Construct the fully qualified queue name.
      String queueName = QueueName.of(projectId, locationId, "default").toString();

      // Construct the task body.
      Task task =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setRelativeUri("/cloudtasks/worker?key=" + key)
                      .setHttpMethod(HttpMethod.POST)
                      .build())
              .build();

      // Add the task to the default queue.
      Task taskResponse = client.createTask(queueName, task);
      System.out.println("Task created: " + taskResponse.getName());
    }

    response.sendRedirect("/");
  }
}

הקובץ שמגדיר את העובד מטפל במשימה:

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(
    name = "TaskWorker",
    description = "Endpoint to process Cloud Task requests",
    urlPatterns = "/cloudtasks/worker"
)
public class Worker extends HttpServlet {

  private static final Logger log = Logger.getLogger(Worker.class.getName());

  // Worker function to process POST requests from Cloud Tasks targeted at the
  // '/cloudtasks/worker' endpoint.
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String key = request.getParameter("key");
    log.info("Worker is processing " + key);
  }
}

המאמרים הבאים