יצירת משימות של יעד HTTP

אפשר להריץ את רכיבי ה-handler של Cloud Tasks בכל נקודת קצה של HTTP עם כתובת IP חיצונית, כמו GKE, ‏ Compute Engine או אפילו שרת אינטרנט מקומי. אפשר להריץ את המשימות שלכם בכל אחד מהשירותים האלה בצורה אמינה וניתנת להגדרה.

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

למשימות עם יעדי HTTP (בניגוד ליעדים מפורשים של App Engine, שהם פחות נפוצים), יש שתי דרכים ליצור משימות:

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

  • BufferTask method: משתמשים בשיטה הזו אם התור מוגדר כך שיאגור משימות לפני שירות. בתור חייבת להיות הגדרת ניתוב ברמת התור. הגישה הזו מתבססת על השיטה BufferTask.

יצירת משימה באמצעות השיטה CreateTask

בקטע הזה מוסבר איך ליצור משימה על ידי בניית אובייקט המשימה. משתמשים בשיטה CreateTask.

כשיוצרים משימה באמצעות CreateTask method, יוצרים ומגדירים במפורש את אובייקט המשימה. צריך לציין את השירות ואת ה-handler שמבצעים את המשימה.

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

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

C#‎


using Google.Cloud.Tasks.V2;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using System;

class CreateHttpTask
{
    public string CreateTask(
        string projectId = "YOUR-PROJECT-ID",
        string location = "us-central1",
        string queue = "my-queue",
        string url = "http://example.com/taskhandler",
        string payload = "Hello World!",
        int inSeconds = 0)
    {
        CloudTasksClient client = CloudTasksClient.Create();
        QueueName parent = new QueueName(projectId, location, queue);

        var response = client.CreateTask(new CreateTaskRequest
        {
            Parent = parent.ToString(),
            Task = new Task
            {
                HttpRequest = new HttpRequest
                {
                    HttpMethod = HttpMethod.Post,
                    Url = url,
                    Body = ByteString.CopyFromUtf8(payload)
                },
                ScheduleTime = Timestamp.FromDateTime(
                    DateTime.UtcNow.AddSeconds(inSeconds))
            }
        });

        Console.WriteLine($"Created Task {response.Name}");
        return response.Name;
    }
}

המשך


// Command createHTTPtask constructs and adds a task to a Cloud Tasks Queue.
package main

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb"
)

// createHTTPTask creates a new task with a HTTP target then adds it to a Queue.
func createHTTPTask(projectID, locationID, queueID, url, message string) (*taskspb.Task, error) {

	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %w", err)
	}

	return createdTask, nil
}

Java

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

public class CreateHttpTask {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    createTask(projectId, locationId, queueId);
  }

  // Create a task with a HTTP target using the Cloud Tasks client.
  public static void createTask(String projectId, String locationId, String queueId)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url = "https://example.com/taskhandler";
      String payload = "Hello, World!";

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

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setUrl(url)
                      .setHttpMethod(HttpMethod.POST)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

שימו לב לקובץ pom.xml:

<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.tasks</groupId>
  <artifactId>cloudtasks-snippets</artifactId>
  <packaging>jar</packaging>
  <name>Google Cloud Tasks Snippets</name>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.2.0</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>libraries-bom</artifactId>
        <version>26.32.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.4.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

// Instantiates a client.
const client = new CloudTasksClient();

async function createHttpTask() {
  // TODO(developer): Uncomment these lines and replace with your values.
  // const project = 'my-project-id';
  // const queue = 'my-queue';
  // const location = 'us-central1';
  // const url = 'https://example.com/taskhandler';
  // const payload = 'Hello, World!';
  // const inSeconds = 180;

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  const task = {
    httpRequest: {
      headers: {
        'Content-Type': 'text/plain', // Set content type to ensure compatibility your application's request parsing
      },
      httpMethod: 'POST',
      url,
    },
  };

  if (payload) {
    task.httpRequest.body = Buffer.from(payload).toString('base64');
  }

  if (inSeconds) {
    // The time when the task is scheduled to be attempted.
    task.scheduleTime = {
      seconds: parseInt(inSeconds) + Date.now() / 1000,
    };
  }

  // Send create task request.
  console.log('Sending task:');
  console.log(task);
  const request = {parent: parent, task: task};
  const [response] = await client.createTask(request);
  console.log(`Created task ${response.name}`);
}
createHttpTask();

שימו לב לקובץ package.json:

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=16.0.0"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "c8 mocha -p -j 2 --timeout 30000",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^5.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^10.0.0",
    "chai": "^4.5.0",
    "mocha": "^10.0.0",
    "uuid": "^11.1.1"
  }
}

PHP

use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
use Google\Cloud\Tasks\V2\CreateTaskRequest;
use Google\Cloud\Tasks\V2\HttpMethod;
use Google\Cloud\Tasks\V2\HttpRequest;
use Google\Cloud\Tasks\V2\Task;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The Location ID';
// $queueId = 'The Cloud Tasks Queue ID';
// $url = 'The full url path that the task request will be sent to.'
// $payload = 'The payload your task should carry to the task handler. Optional';

// Instantiate the client and queue name.
$client = new CloudTasksClient();
$queueName = $client->queueName($projectId, $locationId, $queueId);

// Create an Http Request Object.
$httpRequest = new HttpRequest();
// The full url path that the task request will be sent to.
$httpRequest->setUrl($url);
// POST is the default HTTP method, but any HTTP method can be used.
$httpRequest->setHttpMethod(HttpMethod::POST);
// Setting a body value is only compatible with HTTP POST and PUT requests.
if (!empty($payload)) {
    $httpRequest->setBody($payload);
}

// Create a Cloud Task object.
$task = new Task();
$task->setHttpRequest($httpRequest);

// Send request and print the task name.
$request = (new CreateTaskRequest())
    ->setParent($queueName)
    ->setTask($task);
$response = $client->createTask($request);
printf('Created task %s' . PHP_EOL, $response->getName());

שימו לב לקובץ composer.json:

{
    "require": {
        "google/cloud-tasks": "^2.0"
    }
}

Python

import datetime
import json
from typing import Dict, Optional

from google.cloud import tasks_v2
from google.protobuf import duration_pb2, timestamp_pb2


def create_http_task(
    project: str,
    location: str,
    queue: str,
    url: str,
    json_payload: Dict,
    scheduled_seconds_from_now: Optional[int] = None,
    task_id: Optional[str] = None,
    deadline_in_seconds: Optional[int] = None,
) -> tasks_v2.Task:
    """Create an HTTP POST task with a JSON payload.
    Args:
        project: The project ID where the queue is located.
        location: The location where the queue is located.
        queue: The ID of the queue to add the task to.
        url: The target URL of the task.
        json_payload: The JSON payload to send.
        scheduled_seconds_from_now: Seconds from now to schedule the task for.
        task_id: ID to use for the newly created task.
        deadline_in_seconds: The deadline in seconds for task.
    Returns:
        The newly created task.
    """

    # Create a client.
    client = tasks_v2.CloudTasksClient()

    # Construct the task.
    task = tasks_v2.Task(
        http_request=tasks_v2.HttpRequest(
            http_method=tasks_v2.HttpMethod.POST,
            url=url,
            headers={"Content-type": "application/json"},
            body=json.dumps(json_payload).encode(),
        ),
        name=(
            client.task_path(project, location, queue, task_id)
            if task_id is not None
            else None
        ),
    )

    # Convert "seconds from now" to an absolute Protobuf Timestamp
    if scheduled_seconds_from_now is not None:
        timestamp = timestamp_pb2.Timestamp()
        timestamp.FromDatetime(
            datetime.datetime.utcnow()
            + datetime.timedelta(seconds=scheduled_seconds_from_now)
        )
        task.schedule_time = timestamp

    # Convert "deadline in seconds" to a Protobuf Duration
    if deadline_in_seconds is not None:
        duration = duration_pb2.Duration()
        duration.FromSeconds(deadline_in_seconds)
        task.dispatch_deadline = duration

    # Use the client to send a CreateTaskRequest.
    return client.create_task(
        tasks_v2.CreateTaskRequest(
            # The queue to add the task to
            parent=client.queue_path(project, location, queue),
            # The task itself
            task=task,
        )
    )

שימו לב לקובץ requirements.txt:

google-cloud-tasks==2.18.0

Ruby

require "google/cloud/tasks"

# Create a Task with an HTTP Target
#
# @param [String] project_id Your Google Cloud Project ID.
# @param [String] location_id Your Google Cloud Project Location ID.
# @param [String] queue_id Your Google Cloud Tasks Queue ID.
# @param [String] url The full path to sent the task request to.
# @param [String] payload The request body of your task.
# @param [Integer] seconds The delay, in seconds, to process your task.
def create_http_task project_id, location_id, queue_id, url, payload: nil, seconds: nil
  # Instantiates a client.
  client = Google::Cloud::Tasks.cloud_tasks

  # Construct the fully qualified queue name.
  parent = client.queue_path project: project_id, location: location_id, queue: queue_id

  # Construct task.
  task = {
    http_request: {
      http_method: "POST",
      url:         url
    }
  }

  # Add payload to task body.
  task[:http_request][:body] = payload if payload

  # Add scheduled time to task.
  if seconds
    timestamp = Google::Protobuf::Timestamp.new
    timestamp.seconds = Time.now.to_i + seconds.to_i
    task[:schedule_time] = timestamp
  end

  # Send create task request.
  puts "Sending task #{task}"

  response = client.create_task parent: parent, task: task

  puts "Created task #{response.name}" if response.name
end

יצירת משימה באמצעות השיטה BufferTask

בקטע הזה מוסבר איך ליצור משימה באמצעות שליחת בקשת HTTP. השיטה שבה משתמשים נקראת BufferTask.

מגבלות

השיטה BufferTask כפופה למגבלות הבאות:

  • ספריות לקוח: השיטה BufferTask לא נתמכת בספריות לקוח.

  • RPC API: השיטה BufferTask לא נתמכת ב-RPC API.

  • ניתוב ברמת המשימה: השיטה הזו לא תומכת בניתוב ברמת המשימה. מכיוון שאין אפשרות להוסיף פרטי ניתוב כשיוצרים משימה בדרך הזו, צריך להשתמש בניתוח ברמת התור (אחרת למשימה לא יהיו פרטי ניתוב). אם התור שלכם עדיין לא משתמש בניתוב ברמת התור, כדאי לעיין במאמר בנושא הגדרת ניתוב ברמת התור למשימות HTTP.

מבצעים קריאה ל-BufferTask.

בדוגמאות הבאות מוצגות דרכים ליצור משימה על ידי שליחת בקשת HTTP POST לנקודת הקצה (endpoint) של Cloud Tasks API buffer.

curl

בקטע הקוד הבא יש דוגמה ליצירת משימה באמצעות המתודה BufferTask באמצעות curl:

curl -X HTTP_METHOD\
"https://cloudtasks.googleapis.com/v2/projects/PROJECT_ID/locations/LOCATION/queues/QUEUE_ID/tasks:buffer" \

מחליפים את מה שכתוב בשדות הבאים:

  • HTTP_METHOD: ה-method של ה-HTTP של הבקשה, לדוגמה GET או POST.
  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud . כדי לקבל את המידע הזה, מריצים את הפקודה הבאה בטרמינל:
    gcloud config get-value project
  • LOCATION: המיקום של התור.
  • QUEUE_ID: המזהה של התור.

Python

from google.cloud import tasks_v2beta3 as tasks

import requests


def send_task_to_http_queue(
    queue: tasks.Queue, body: str = "", token: str = "", headers: dict = {}
) -> int:
    """Send a task to an HTTP queue.
    Args:
        queue: The queue to send task to.
        body: The body of the task.
        auth_token: An authorization token for the queue.
        headers: Headers to set on the task.
    Returns:
        The matching queue, or None if it doesn't exist.
    """

    # Use application default credentials if not supplied in a header
    if token:
        headers["Authorization"] = f"Bearer {token}"

    endpoint = f"https://cloudtasks.googleapis.com/v2beta3/{queue.name}/tasks:buffer"
    response = requests.post(endpoint, body, headers=headers)

    return response.status_code

הגדרה של חשבון שירות לאימות של מטפל ביעד HTTP

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

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

  1. נכנסים לדף Service Accounts במסוף Google Cloud .

    לדף Service accounts

  2. אם צריך, בוחרים את הפרויקט המתאים.

  3. לוחצים על Create service account (יצירת חשבון שירות).

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

  5. לוחצים על Create and continue.

  6. ברשימה Select a role, מחפשים את Cloud Tasks Enqueuer (Beta) ובוחרים אותו. התפקיד הזה נותן לחשבון השירות הרשאה להוסיף משימות לתור.

  7. אם משתמשים ב Google Cloud handler, לוחצים על + Add another role כדי להעניק לחשבון השירות את התפקיד שמשויך לגישה לשירות שבו ה-handler פועל. לכל שירות ב- Google Cloud נדרש תפקיד אחר. לדוגמה, כדי לגשת ל-handler ב-Cloud Run, צריך להקצות את התפקיד Cloud Run Invoker.

  8. כדי לסיים את יצירת חשבון השירות, לוחצים על Done.

  9. כדי לאפשר ל-Cloud Tasks ליצור אסימוני אימות באמצעות חשבון השירות שיצרתם, אתם צריכים להקצות את התפקיד משתמש בחשבון שירות (roles/iam.serviceAccountUser) לסוכן השירות הראשי של Cloud Tasks (roles/iam.serviceAccountUser) בחשבון השירות שיצרתם.

    1. נכנסים לדף Service accounts במסוף Google Cloud .

      כניסה לדף Service accounts

    2. בשורה של חשבון השירות שיצרתם, מסמנים את תיבת הסימון ואז לוחצים על Manage access (ניהול גישה).

    3. בחלונית Manage Access, לוחצים על Add principal.

    4. ברשימה New principals, מחפשים ובוחרים את סוכן השירות של Cloud Tasks, שתהיה לו כתובת אימייל בפורמט service-PROJECT_NUMBER@gcp-sa-cloudtasks.iam.gserviceaccount.com.

    5. ברשימה Select a role מחפשים את התפקיד Service Account User ובוחרים אותו.

    6. לוחצים על Save.

שימוש במשימות של יעד HTTP עם אסימוני אימות

כדי לבצע אימות בין Cloud Tasks לבין handler של יעד HTTP שנדרש לו אימות כזה, Cloud Tasks יוצר אסימון כותרת. האסימון הזה מבוסס על פרטי הכניסה בחשבון השירות Cloud Tasks Enqueuer, שמזוהה באמצעות כתובת האימייל שלו. חשבון השירות שמשמש לאימות צריך להיות חלק מאותו פרויקט שבו נמצא התור של Cloud Tasks. הבקשה, עם אסימון הכותרת, נשלחת מהתור ל-handler באמצעות HTTPS. אפשר להשתמש באסימון מזהה או באסימון גישה. באופן כללי, כדאי להשתמש באסימונים מזהים לכל handler שפועל ב- Google Cloud, למשל בפונקציות של Cloud Run או ב-Cloud Run. החריג העיקרי הוא ממשקי Google API שמארחים ב-*.googleapis.com: ממשקי ה-API האלה מצפים לאסימון גישה.

אפשר להגדיר אימות ברמת התור או ברמת המשימה. כדי להגדיר אימות ברמת התור, אפשר לעיין במאמר בנושא הגבלת הגישה לתורים ספציפיים. אם האימות מוגדר ברמת התור, ההגדרה הזו מחליפה את ההגדרה ברמת המשימה. כדי להגדיר אימות ברמת המשימה, צריך לציין אסימון מזהה (OIDC) או אסימון גישה (OAuth) במשימה עצמה.

CreateTask method

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

המשך

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb"
)

// createHTTPTaskWithToken constructs a task with a authorization token
// and HTTP target then adds it to a Queue.
func createHTTPTaskWithToken(projectID, locationID, queueID, url, email, message string) (*taskspb.Task, error) {
	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
					AuthorizationHeader: &taskspb.HttpRequest_OidcToken{
						OidcToken: &taskspb.OidcToken{
							ServiceAccountEmail: email,
						},
					},
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %w", err)
	}

	return createdTask, nil
}

Java

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.HttpRequest;
import com.google.cloud.tasks.v2.OidcToken;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;

public class CreateHttpTaskWithToken {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    String serviceAccountEmail =
        "java-docs-samples-testing@java-docs-samples-testing.iam.gserviceaccount.com";
    createTask(projectId, locationId, queueId, serviceAccountEmail);
  }

  // Create a task with a HTTP target and authorization token using the Cloud Tasks client.
  public static void createTask(
      String projectId, String locationId, String queueId, String serviceAccountEmail)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url =
          "https://example.com/taskhandler"; // The full url path that the request will be sent to
      String payload = "Hello, World!"; // The task HTTP request body

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

      // Add your service account email to construct the OIDC token.
      // in order to add an authentication header to the request.
      OidcToken.Builder oidcTokenBuilder =
          OidcToken.newBuilder().setServiceAccountEmail(serviceAccountEmail);

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setHttpMethod(HttpMethod.POST)
                      .setUrl(url)
                      .setOidcToken(oidcTokenBuilder)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

שימו לב לקובץ pom.xml:

<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.tasks</groupId>
  <artifactId>cloudtasks-snippets</artifactId>
  <packaging>jar</packaging>
  <name>Google Cloud Tasks Snippets</name>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.2.0</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>libraries-bom</artifactId>
        <version>26.32.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.4.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

// Instantiates a client.
const client = new CloudTasksClient();

async function createHttpTaskWithToken() {
  // TODO(developer): Uncomment these lines and replace with your values.
  // const project = 'my-project-id';
  // const queue = 'my-queue';
  // const location = 'us-central1';
  // const url = 'https://example.com/taskhandler';
  // const serviceAccountEmail = 'client@<project-id>.iam.gserviceaccount.com';
  // const payload = 'Hello, World!';

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  const task = {
    httpRequest: {
      headers: {
        'Content-Type': 'text/plain', // Set content type to ensure compatibility your application's request parsing
      },
      httpMethod: 'POST',
      url,
      oidcToken: {
        serviceAccountEmail,
      },
    },
  };

  if (payload) {
    task.httpRequest.body = Buffer.from(payload).toString('base64');
  }

  console.log('Sending task:');
  console.log(task);
  // Send create task request.
  const request = {parent: parent, task: task};
  const [response] = await client.createTask(request);
  const name = response.name;
  console.log(`Created task ${name}`);
}
createHttpTaskWithToken();

שימו לב לקובץ package.json:

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=16.0.0"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "c8 mocha -p -j 2 --timeout 30000",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^5.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^10.0.0",
    "chai": "^4.5.0",
    "mocha": "^10.0.0",
    "uuid": "^11.1.1"
  }
}

Python

from typing import Optional

from google.cloud import tasks_v2


def create_http_task_with_token(
    project: str,
    location: str,
    queue: str,
    url: str,
    payload: bytes,
    service_account_email: str,
    audience: Optional[str] = None,
) -> tasks_v2.Task:
    """Create an HTTP POST task with an OIDC token and an arbitrary payload.
    Args:
        project: The project ID where the queue is located.
        location: The location where the queue is located.
        queue: The ID of the queue to add the task to.
        url: The target URL of the task.
        payload: The payload to send.
        service_account_email: The service account to use for generating the OIDC token.
        audience: Audience to use when generating the OIDC token.
    Returns:
        The newly created task.
    """

    # Create a client.
    client = tasks_v2.CloudTasksClient()

    # Construct the request body.
    task = tasks_v2.Task(
        http_request=tasks_v2.HttpRequest(
            http_method=tasks_v2.HttpMethod.POST,
            url=url,
            oidc_token=tasks_v2.OidcToken(
                service_account_email=service_account_email,
                audience=audience,
            ),
            body=payload,
        ),
    )

    # Use the client to build and send the task.
    return client.create_task(
        tasks_v2.CreateTaskRequest(
            parent=client.queue_path(project, location, queue),
            task=task,
        )
    )

שימו לב לקובץ requirements.txt:

google-cloud-tasks==2.18.0

BufferTask method

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

curl

curl -X HTTP_METHOD\
"https://cloudtasks.googleapis.com/v2/projects/PROJECT_ID/locations/LOCATION/queues/QUEUE_ID/tasks:buffer" \
    -H "Authorization: Bearer ACCESS_TOKEN"

מחליפים את מה שכתוב בשדות הבאים:

  • HTTP_METHOD: ה-method של ה-HTTP של הבקשה, לדוגמה GET או POST.
  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud . כדי לקבל את המידע הזה, מריצים את הפקודה הבאה בטרמינל:
    gcloud config get-value project
  • LOCATION: המיקום של התור.
  • QUEUE_ID: המזהה של התור.
  • ACCESS_TOKEN: אסימון הגישה. אפשר לקבל את זה על ידי הרצת הפקודה הבאה במסוף:
  • gcloud auth application-default login
  • gcloud auth application-default print-access-token

Python

בדוגמת הקוד הבאה, צריך לציין את ערך טוקן האימות.

from google.cloud import tasks_v2beta3 as tasks

import requests


def send_task_to_http_queue(
    queue: tasks.Queue, body: str = "", token: str = "", headers: dict = {}
) -> int:
    """Send a task to an HTTP queue.
    Args:
        queue: The queue to send task to.
        body: The body of the task.
        auth_token: An authorization token for the queue.
        headers: Headers to set on the task.
    Returns:
        The matching queue, or None if it doesn't exist.
    """

    # Use application default credentials if not supplied in a header
    if token:
        headers["Authorization"] = f"Bearer {token}"

    endpoint = f"https://cloudtasks.googleapis.com/v2beta3/{queue.name}/tasks:buffer"
    response = requests.post(endpoint, body, headers=headers)

    return response.status_code

הוספת מטפלים משלכם במשימות של יעד HTTP

מטפלי משימות של יעד HTTP דומים מאוד למטפלי משימות של App Engine, עם ההבדלים הבאים:

  • זמן קצוב לתפוגה: בכל המטפלים במשימות של HTTP Target, ברירת המחדל של הזמן הקצוב לתפוגה היא 10 דקות, והמקסימום הוא 30 דקות.
  • לוגיקת אימות: אם אתם כותבים קוד משלכם בשירות המטרה כדי לאמת את האסימון, אתם צריכים להשתמש באסימון מזהה. למידע נוסף על המשמעות של זה, תוכלו לקרוא את המאמר OpenID Connect, ובמיוחד את הקטע אימות אסימון מזהה.
  • כותרות: לבקשת יעד HTTP יש כותרות שמוגדרות על ידי התור, והן מכילות מידע ספציפי למשימה שהמטפל יכול להשתמש בו. הן דומות לכותרות שמוגדרות בבקשות למשימות ב-App Engine, אבל לא זהות להן. הכותרות האלה מספקות מידע בלבד. אין להשתמש בהם כמקורות לזיהוי.

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

    בקשות יעד של HTTP תמיד מכילות את הכותרות הבאות:

    כותרת תיאור
    X-CloudTasks-QueueName שם התור.
    X-CloudTasks-TaskName השם ה "קצר" של המשימה, או, אם לא צוין שם כשנוצרה, מזהה ייחודי שנוצר על ידי המערכת. זהו הערך my-task-id בשם המשימה המלא, כלומר, task_name = projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id.
    X-CloudTasks-TaskRetryCount מספר הפעמים שהייתה ניסיון חוזר להפעלת המשימה. בניסיון הראשון, הערך הוא 0. המספר הזה כולל ניסיונות שבהם המשימה נכשלה בגלל קודי שגיאה 5XX ולא הגיעה לשלב הביצוע.
    X-CloudTasks-TaskExecutionCount המספר הכולל של הפעמים שהמשימה קיבלה תגובה מהמטפל. מכיוון ש-Cloud Tasks מוחק את המשימה אחרי קבלת תגובה מוצלחת, כל התגובות הקודמות של ה-handler היו כשלים. המספר הזה לא כולל כשלים בגלל קודי שגיאה מסוג 5XX.
    X-CloudTasks-TaskETA בתחילה, השעה המקורית שנקבעה למשימה, שצוינה בשניות מאז 1 בינואר 1970. שימו לב שהערך הזה מייצג את זמן השילוח הצפוי. בניסיונות חוזרים, הערך מתעדכן קרוב יותר לשעה הנוכחית ואפשר להשתמש בו כדי למדוד את זמן האחזור של המסירה. אין להשתמש בו לביטול כפילויות של משימות.

    בנוסף, בקשות מ-Cloud Tasks עשויות להכיל את הכותרות הבאות:

    כותרת תיאור
    X-CloudTasks-TaskPreviousResponse קוד תגובת ה-HTTP מהניסיון הקודם.
    X-CloudTasks-TaskRetryReason הסיבה לניסיון החוזר של המשימה.

הוספה ידנית של התפקיד Cloud Tasks Service Agent

אפשר להוסיף באופן ידני את התפקיד Cloud Tasks Service Agent ‏(roles/cloudtasks.serviceAgent) לחשבון השירות של Cloud Tasks, שהוא סוכן השירות הראשי של Cloud Tasks.

הפעולה הזו נדרשת רק אם הפעלתם את Cloud Tasks API לפני 19 במרץ 2019.

המסוף

  1. בדף Welcome במסוף Google Cloud , מוצאים את מספר הפרויקט ומעתיקים אותו. Google Cloud
  2. נכנסים לדף IAM במסוף Google Cloud .

    כניסה לדף IAM

  3. לוחצים על הענקת גישה. נפתחת החלונית הענקת גישה.

  4. בקטע Add principals (הוספת בעלי הרשאה), מוסיפים כתובת אימייל בפורמט הבא:

     service-PROJECT_NUMBER@gcp-sa-cloudtasks.iam.gserviceaccount.com
     

    מחליפים את PROJECT_NUMBER ב Google Cloud מספר הפרויקט.

  5. בקטע Assign roles, מחפשים את Cloud Tasks Service Agent ובוחרים אותו.

  6. לוחצים על Save.

gcloud

  1. כדי למצוא את מספר הפרויקט:

    gcloud projects describe PROJECT_ID --format='table(projectNumber)'

    מחליפים את PROJECT_ID במזהה הפרויקט.

  2. מעתיקים את המספר.

  3. מקצים לחשבון השירות של Cloud Tasks את התפקיד Cloud Tasks Service Agent באמצעות מספר הפרויקט שהעתקתם:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:service-PROJECT_NUMBER@gcp-sa-cloudtasks.iam.gserviceaccount.com \
        --role roles/cloudtasks.serviceAgent

    מחליפים את מה שכתוב בשדות הבאים:

    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • PROJECT_NUMBER: מספר הפרויקט ב- Google Cloud.

הגדרות אחרות

יש מספר מאפיינים של משימות שאפשר להגדיר. רשימה מלאה זמינה בהגדרת משאב המשימה. לדוגמה, אפשר להתאים אישית את המאפיינים הבאים:

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

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

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