מסירה בדיוק פעם אחת

בדף הזה מוסבר איך לקבל הודעות ולאשר את קבלתן באמצעות התכונה 'פעם אחת בדיוק' של Pub/Sub, שמאפשרת לכם לעקוב אחרי עיבוד כפול של הודעות ולמנוע אותו. כשהתכונה מופעלת, Pub/Sub מספק את הסמנטיקה הבאה:

  • המנויים יכולים לדעת אם אישורי המסירה של ההודעות התקבלו.

  • לא מתבצעת מסירה חוזרת אחרי שההודעה מאושרת בהצלחה.

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

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

אם האפשרות 'עיבוד בדיוק פעם אחת' מופעלת, המנויים יכולים לוודא שההודעות יעובדו פעם אחת על ידי ביצוע ההנחיות הבאות:

  • לאשר את קבלת ההודעות לפני המועד האחרון לאישור.

  • שמירת מידע על התקדמות העיבוד של הודעה עד לקבלת אישור מוצלח.

  • אפשר להשתמש במידע על התקדמות העיבוד של הודעה כדי למנוע כפילויות בעבודה כשאישור נכשל.

רק סוג המינוי pull תומך בשליחה בדיוק פעם אחת, כולל מנויים שמשתמשים ב-StreamingPull API. מינויים להעברת נתונים וייצוא לא תומכים במסירה של כל נתון בדיוק פעם אחת.

ב-Pub/Sub יש תמיכה בשליחה של כל הודעה בדיוק פעם אחת, באזור ענן, על סמך מזהה הודעה ייחודי שמוגדר ב-Pub/Sub.

העברה חוזרת לעומת כפילות

חשוב להבין את ההבדל בין מסירות חוזרות צפויות לבין מסירות חוזרות לא צפויות.

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

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

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

  • הודעה שנשלחה מחדש שומרת על אותו מזהה הודעה בין ניסיונות השליחה מחדש.

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

תמיכה באספקה בדיוק פעם אחת בספריות לקוח

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

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

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

  • אם אתם משתמשים בספריית הלקוח של Java ומאתחלים את המנוי שלכם באמצעות ערוץ gRPC בהתאמה אישית באמצעות השיטה setChannelProvider(), מומלץ גם להגדיר את maxInboundMetadataSize ל-1MB לפחות כשיוצרים את TransportChannelProvider. כדי להגדיר את זה, אפשר להשתמש בשיטה InstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize() או בשיטה ManagedChannelBuilder.maxInboundMetadataSize().

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

משתנה תיאור ערך
setEnableExactlyOnceDelivery המתג מפעיל או משבית את האפשרות 'משלוח פעם אחת בלבד'. true or false Default=false
minDurationPerAckExtension הזמן המינימלי בשניות שמשמש להארכת המועד האחרון לאישור השינוי. טווח=0 עד 600 ברירת מחדל=ללא
maxDurationPerAckExtension פרק הזמן המקסימלי בשניות שבו אפשר להשתמש כדי להאריך את המועד האחרון לאישור שינוי. טווח=0 עד 600 ברירת מחדל=ללא

במקרה של מסירה בדיוק פעם אחת, הבקשה modifyAckDeadline או acknowledgment ל-Pub/Sub נכשלת כשמזהה האישור כבר פג. במקרים כאלה, השירות מחשיב את מזהה האישור שפג תוקפו כלא תקף, כי יכול להיות שמשלוח חדש יותר כבר בדרך. זהו התנהגות מכוונת של המערכת כדי להבטיח מסירה של כל הודעה בדיוק פעם אחת. אחרי זה רואים שבקשות acknowledgment ו-ModifyAckDeadline מחזירות תגובה INVALID_ARGUMENT. כשמשביתים את האפשרות 'שליחה בדיוק פעם אחת', הבקשות האלה מחזירות OK במקרים של מזהי אישור שפג תוקפם.

כדי לוודא שלבקשות acknowledgment ו-ModifyAckDeadline יש מזהי אישור תקינים, כדאי להגדיר את הערך של minDurationPerAckExtension למספר גבוה.

שיקולים אזוריים

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

כשמריצים את האפליקציה ב- Google Cloud, היא מתחברת כברירת מחדל לנקודת הקצה של Pub/Sub באותו אזור. לכן, הפעלת האפליקציה באזור אחד בתוך Google Cloudבדרך כלל מבטיחה אינטראקציה עם אזור אחד.

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

יצירת מינויים עם מסירה של הודעה בדיוק פעם אחת

אפשר ליצור מינוי עם מסירה בדיוק פעם אחת באמצעות מסוף Google Cloud , Google Cloud CLI, ספריית לקוח או Pub/Sub API.

מינוי שליפה

המסוף

כדי ליצור מינוי מסוג pull עם מסירה בדיוק פעם אחת, פועלים לפי השלבים הבאים:

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

    אל הדף "מינויים"

  2. לוחצים על יצירת מינוי.

  3. מזינים את מזהה המינוי.

  4. בוחרים נושא מהתפריט הנפתח או יוצרים נושא חדש.

    המינוי מקבל הודעות מהנושא.

  5. בקטע Exactly once delivery (אספקה בדיוק פעם אחת), בוחרים באפשרות Enable exactly once delivery (הפעלת אספקה בדיוק פעם אחת).

  6. לוחצים על יצירה.

gcloud

כדי ליצור מינוי מסוג pull עם מסירה בדיוק פעם אחת, משתמשים בפקודה gcloud pubsub subscriptions create עם הדגל --enable-exactly-once-delivery:

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=TOPIC_ID \
  --enable-exactly-once-delivery

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

  • SUBSCRIPTION_ID: המזהה של המינוי שרוצים ליצור
  • TOPIC_ID: המזהה של הנושא לצירוף למינוי

REST

כדי ליצור מינוי עם מסירה בדיוק פעם אחת, משתמשים בשיטה projects.subscriptions.create.

PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Authorization: Bearer $(gcloud auth print-access-token)

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

  • PROJECT_ID: מזהה הפרויקט שבו רוצים ליצור את המינוי
  • SUBSCRIPTION_ID: המזהה של המינוי שרוצים ליצור

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

{
  "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
  "enableExactlyOnceDelivery": true,
}

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

  • PROJECT_ID: מזהה הפרויקט של הפרויקט עם הנושא
  • TOPIC_ID: המזהה של הנושא לצירוף למינוי

C++‎

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C++‎ במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף זמין במאמרי העזרה של Pub/Sub C++ API.

namespace pubsub = ::google::cloud::pubsub;
namespace pubsub_admin = ::google::cloud::pubsub_admin;
[](pubsub_admin::SubscriptionAdminClient client,
   std::string const& project_id, std::string const& topic_id,
   std::string const& subscription_id) {
  google::pubsub::v1::Subscription request;
  request.set_name(
      pubsub::Subscription(project_id, subscription_id).FullName());
  request.set_topic(pubsub::Topic(project_id, topic_id).FullName());
  request.set_enable_exactly_once_delivery(true);
  auto sub = client.CreateSubscription(request);
  if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The subscription already exists\n";
    return;
  }
  if (!sub) throw std::move(sub).status();

  std::cout << "The subscription was successfully created: "
            << sub->DebugString() << "\n";
}

C#‎

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של C# ‎ במאמר הפעלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub C# API.


using Google.Cloud.PubSub.V1;
using Grpc.Core;

public class CreateSubscriptionWithExactlyOnceDeliverySample
{
    public Subscription CreateSubscriptionWithExactlyOnceDelivery(string projectId, string topicId, string subscriptionId)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);
        SubscriptionName subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);

        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            EnableExactlyOnceDelivery = true
        };

        Subscription subscription = null;

        try
        {
            subscription = subscriber.CreateSubscription(subscriptionRequest);
        }
        catch (RpcException e) when (e.Status.StatusCode == StatusCode.AlreadyExists)
        {
            // Already exists.  That's fine.
        }
        return subscription;
    }
}

המשך

בדוגמה הבאה נעשה שימוש בגרסה הראשית של ספריית הלקוח Go Pub/Sub ‏ (v2). אם אתם עדיין משתמשים בספרייה v1, כדאי לעיין במדריך להעברה לגרסה v2. כדי לראות רשימה של דוגמאות קוד מגרסה 1, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Go במאמר מדריך למתחילים: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Go API.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub/v2"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

func createSubscriptionWithExactlyOnceDelivery(w io.Writer, projectID, topic, subscription string) error {
	// projectID := "my-project-id"
	// topic := "projects/my-project-id/topics/my-topic"
	// subscription := "projects/my-project/subscriptions/my-sub"
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	pbSub := &pubsubpb.Subscription{
		Name:                      subscription,
		Topic:                     topic,
		EnableExactlyOnceDelivery: true,
	}
	sub, err := client.SubscriptionAdminClient.CreateSubscription(ctx, pbSub)
	if err != nil {
		return fmt.Errorf("failed to create exactly once sub: %w", err)
	}
	fmt.Fprintf(w, "Created a subscription with exactly once delivery enabled: %v\n", sub)
	return nil
}

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Java במאמר תחילת העבודה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Java API.

import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.Subscription;
import java.io.IOException;

public class CreateSubscriptionWithExactlyOnceDelivery {
  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String topicId = "your-topic-id";
    String subscriptionId = "your-subscription-id";

    createSubscriptionWithExactlyOnceDeliveryExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithExactlyOnceDeliveryExample(
      String projectId, String topicId, String subscriptionId) throws IOException {
    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {

      ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      Subscription subscription =
          subscriptionAdminClient.createSubscription(
              Subscription.newBuilder()
                  .setName(subscriptionName.toString())
                  .setTopic(topicName.toString())
                  // Enable exactly once delivery in the subscription.
                  .setEnableExactlyOnceDelivery(true)
                  .build());

      System.out.println(
          "Created a subscription with exactly once delivery enabled: "
              + subscription.getAllFields());
    }
  }
}

Python

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Python במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של ה-API בשפת Python של Pub/Sub.

from google.cloud import pubsub_v1

# TODO(developer): Choose an existing topic.
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

publisher = pubsub_v1.PublisherClient()
subscriber = pubsub_v1.SubscriberClient()
topic_path = publisher.topic_path(project_id, topic_id)
subscription_path = subscriber.subscription_path(project_id, subscription_id)

with subscriber:
    subscription = subscriber.create_subscription(
        request={
            "name": subscription_path,
            "topic": topic_path,
            "enable_exactly_once_delivery": True,
        }
    )
    print(
        f"Created subscription with exactly once delivery enabled: {subscription}"
    )

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר הפעלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';

// Imports the Google Cloud client library
const {PubSub} = require('@google-cloud/pubsub');

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createSubscriptionWithExactlyOnceDelivery(
  topicNameOrId,
  subscriptionNameOrId,
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableExactlyOnceDelivery: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with exactly-once delivery.`,
  );
  console.log(
    'To process messages, remember to check the return value of ackWithResponse().',
  );
}

Node.js

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Node.js במאמר תחילת העבודה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Node.js API.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';

// Imports the Google Cloud client library
import {PubSub} from '@google-cloud/pubsub';

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createSubscriptionWithExactlyOnceDelivery(
  topicNameOrId: string,
  subscriptionNameOrId: string,
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableExactlyOnceDelivery: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with exactly-once delivery.`,
  );
  console.log(
    'To process messages, remember to check the return value of ackWithResponse().',
  );
}

Ruby

בדוגמה הבאה נעשה שימוש בספריית הלקוח של Ruby Pub/Sub בגרסה 3. אם אתם עדיין משתמשים בספרייה v2, כדאי לעיין במדריך להעברה לגרסה v3. כדי לראות רשימה של דוגמאות קוד של Ruby v2, אפשר לעיין ב דוגמאות הקוד שהוצאו משימוש.

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של Ruby במאמר תחילת העבודה המהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub Ruby API.

# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

pubsub = Google::Cloud::PubSub.new project_id: project_id
subscription_admin = pubsub.subscription_admin

subscription = subscription_admin.create_subscription \
  name: pubsub.subscription_path(subscription_id),
  topic: pubsub.topic_path(topic_id),
  enable_exactly_once_delivery: true

puts "Created subscription with exactly once delivery enabled: " \
     "#{subscription_id}"

PHP

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי הוראות ההגדרה של PHP במאמר התחלה מהירה: שימוש בספריות לקוח. מידע נוסף מופיע במאמרי העזרה של Pub/Sub PHP API.

use Google\Cloud\PubSub\PubSubClient;

/**
 * Creates a Pub/Sub subscription with `Exactly Once Delivery` enabled.
 *
 * @param string $projectId  The Google project ID.
 * @param string $topicName  The Pub/Sub topic name.
 * @param string $subscriptionName  The Pub/Sub subscription name.
 */
function create_subscription_with_exactly_once_delivery(
    string $projectId,
    string $topicName,
    string $subscriptionName
): void {
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $subscription = $topic->subscription($subscriptionName);
    $subscription->create([
        'enableExactlyOnceDelivery' => true
    ]);

    // Exactly Once Delivery status for the subscription
    $status = $subscription->info()['enableExactlyOnceDelivery'];

    printf('Subscription created with exactly once delivery status: %s' . PHP_EOL, $status ? 'true' : 'false');
}

מעקב אחר מינויים עם מסירה בדיוק פעם אחת

המדד subscription/exactly_once_warning_count מתעד את מספר האירועים שיכולים להוביל למסירה חוזרת (תקינה או כפולה). המדד הזה סופר את מספר הפעמים שבהן Pub/Sub לא מצליח לעבד בקשות שמשויכות למזהי אישור (בקשת ModifyAckDeadline או acknowledgment). הסיבות לכשל יכולות להיות קשורות לשרת או ללקוח. לדוגמה, אם שכבת ההתמדה שמשמשת לשמירת פרטי המסירה בדיוק פעם אחת לא זמינה, זה יהיה אירוע מבוסס-שרת. אם הלקוח מנסה לאשר קבלת הודעה עם מזהה אישור קבלה לא תקין, זה יהיה אירוע מבוסס-לקוח.

הסבר על המדד

subscription/exactly_once_warning_count מתעד אירועים שעשויים להוביל או לא להוביל למסירות חוזרות בפועל, ויכול להיות שיהיו בו הרבה נתונים לא רלוונטיים בהתאם להתנהגות הלקוח. לדוגמה: בקשות חוזרות מסוג acknowledgment או ModifyAckDeadline עם מזהי אישור לא תקינים מגדילות את המדד שוב ושוב.

המדדים הבאים יכולים לעזור לכם להבין את התנהגות הלקוח:

  • subscription/expired_ack_deadlines_count המדד הזה מציג את מספר הפעמים שפג התוקף של מזהה אישור. תפוגה של מזהה אישור יכולה להוביל לכשלים בבקשות ModifyAckDeadline וגם בבקשות acknowledgment.

  • אפשר להשתמש במדד service.serviceruntime.googleapis.com/api/request_count כדי לתעד כשלים בבקשות של ModifyAckDeadline או acknowledgment במקרים שבהם הבקשות מגיעות אל Google Cloud אבל לא מגיעות אל Pub/Sub. יש כשלים שהמדד הזה לא יתעד – למשל, כשלקוחות מנותקים מ- Google Cloud.

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

מכסות

מינויים עם מסירה בדיוק פעם אחת כפופים לדרישות נוספות של מכסת שימוש. המכסות האלה נאכפות ב:

  • מספר ההודעות שנצרכו מהמינויים עם האפשרות 'מסירה בדיוק פעם אחת' מופעלת לכל אזור.
  • מספר ההודעות שהתקבלו או שהמועד האחרון שלהן הוארך כשמשתמשים במינויים עם האפשרות 'שליחה בדיוק פעם אחת' שמופעלת לכל אזור.

מידע נוסף על המכסות האלה זמין בטבלה שבנושא מכסות.

משלוח בדיוק פעם אחת ומינויים מסודרים

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

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

שליחת הודעות למינויים בדיוק פעם אחת

ב-Pub/Sub יש תמיכה בשליחה של הודעה אחת בלבד רק במינויי pull.

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

חשוב לדעת

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

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

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

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

  • מינוי עשוי לקבל כמה עותקים של אותו הודעה בגלל כפילויות בצד הפרסום, גם אם האפשרות 'מסירה בדיוק פעם אחת' מופעלת. כפילויות בצד הפרסום יכולות לקרות בגלל ניסיונות חוזרים לפרסום ייחודי על ידי לקוח הפרסום או שירות Pub/Sub. פרסומים ייחודיים רבים על ידי לקוח הפרסום, במהלך ניסיונות חוזרים, מובילים למסירה חוזרת עם מזהי הודעות שונים. פרסום ייחודי של שירות Pub/Sub בתגובה לבקשת פרסום של לקוח מוביל למסירה חוזרת עם אותם מזהי הודעות.

  • אפשר לנסות שוב פעולות שנכשלו ב-subscription/exactly_once_warning_count, וספריות הלקוח הנתמכות מנסות שוב את הפעולות האלה באופן אוטומטי. עם זאת, אי אפשר לנסות שוב לבצע פעולות שנכשלו בגלל מזהי אישור לא תקינים.