יצירת משימות ב-App Engine באופן פרוגרמטי

במאמר הזה נסביר איך ליצור באופן פרוגרמטי משימות של App Engine ולהוסיף אותן לתורים של Cloud Tasks.

בתהליך הזה אפשר לציין במפורש את השירות ואת ה-handler שאמורים לעבד את המשימה, ואפשר גם להעביר ל-handler נתונים ספציפיים למשימה. שירות Cloud Tasks מעביר את בקשת המשימה ל-handler, אבל העובד הזה נמצא ב-App Engine. לכן, לכל התורים שמטרגטים ל-handlers של App Engine צריך להיות App Engine app. ה-handlers צריכים לפעול באזור שבו פועל ה-App Engine app. האזור הזה משמש גם כפרמטר LOCATION_ID בבקשות שלכם ל-Cloud Tasks. מידע נוסף זמין במאמר תורים של Cloud Tasks עם יעדים של App Engine.

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

אפשר גם ליצור משימות ב-App Engine באמצעות Google Cloud CLI או באמצעות שליחת בקשה ישירה אל Cloud Tasks API. מידע נוסף זמין במאמר יצירת משימות.

כללים לחומת אש ב-App Engine

בסביבה הרגילה של App Engine, חומת האש של App Engine יכולה לאפשר לתנועה פנימית מסוימת לעקוף את חומת האש. כלומר, אם מגדירים את הכלל default לערך deny, בקשות משירותים מסוימים שמיועדות לסביבת App Engine standard לא נחסמות. אלה כל סוגי התנועה שנדרשים בהגדרה של האפליקציה עצמה, או שנשלחים מאותה אפליקציה. בקשות שעוקפות את כללי חומת האש בדרך הזו כוללות גם משימות של App Engine ב-Cloud Tasks (כולל תורי משימות של App Engine).

כדי לאפשר בקשות נכנסות, אלה טווחי כתובות ה-IP למשימות של App Engine ב-Cloud Tasks (כולל תורי משימות של App Engine):

  • טווח כתובות ה-IP לבקשות שנשלחות לסביבה הרגילה של App Engine: ‏ 0.1.0.2/32 (עוקף את כלל ברירת המחדל של חומת האש אם הוא מוגדר כדחייה)

  • טווח כתובות ה-IP של בקשות שנשלחות לסביבה הגמישה של App Engine: ‏ 0.1.0.2/32

יצירת משימות באמצעות ספריות לקוח

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

C#‎


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

class CreateAppEngineTask
{
    public string CreateTask(
        // TODO<developer>: call this method by passing correct values for
        // the following parameters or change the parameters' default values.
        string projectId = "YOUR-PROJECT-ID",
        string location = "us-central1",
        string queue = "my-queue",
        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
            {
                AppEngineHttpRequest = new AppEngineHttpRequest
                {
                    HttpMethod = HttpMethod.Post,
                    RelativeUri = "/log_payload",
                    Body = ByteString.CopyFromUtf8(payload)
                },
                ScheduleTime = Timestamp.FromDateTime(
                    DateTime.UtcNow.AddSeconds(inSeconds))
            }
        });

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

המשך


// Command create_task constructs and adds a task to an App Engine Queue.
package main

import (
	"context"
	"fmt"

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

// createTask creates a new task in your App Engine queue.
func createTask(projectID, locationID, queueID, 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#AppEngineHttpRequest
			MessageType: &taskspb.Task_AppEngineHttpRequest{
				AppEngineHttpRequest: &taskspb.AppEngineHttpRequest{
					HttpMethod:  taskspb.HttpMethod_POST,
					RelativeUri: "/task_handler",
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetAppEngineHttpRequest().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.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 com.google.protobuf.Timestamp;
import java.io.IOException;
import java.nio.charset.Charset;
import java.time.Clock;
import java.time.Instant;

public class CreateTask {
  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String queue = "my-appengine-queue";
    String location = "us-central1";
    String payload = "hello";
    int seconds = 0; // Scheduled delay for the task in seconds
    createTask(projectId, queue, location, payload, seconds);
  }

  // This is an example snippet for showing best practices.
  public static void createTask(
      String projectId, String queueName, String location, String payload, int seconds)
      throws IOException {
    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      // Construct the fully qualified queue name.
      String queuePath = QueueName.of(projectId, location, queueName).toString();

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setRelativeUri("/tasks/create")
                      .setHttpMethod(HttpMethod.POST)
                      .build());

      // Add the scheduled time to the request.
      taskBuilder.setScheduleTime(
          Timestamp.newBuilder()
              .setSeconds(Instant.now(Clock.systemUTC()).plusSeconds(seconds).getEpochSecond()));

      // 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"?>
<!--
Copyright 2019 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");