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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

מינוי שליפה

המסוף

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

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

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

  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');
}

חלודה

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

use google_cloud_pubsub::client::SubscriptionAdmin;

pub async fn sample(
    client: &SubscriptionAdmin,
    project_id: &str,
    topic_id: &str,
    subscription_id: &str,
) -> anyhow::Result<()> {
    let subscription_name = format!("projects/{project_id}/subscriptions/{subscription_id}");
    let topic_name = format!("projects/{project_id}/topics/{topic_id}");

    let subscription = client
        .create_subscription()
        .set_name(subscription_name)
        .set_topic(topic_name)
        .set_enable_exactly_once_delivery(true)
        .send()
        .await?;

    println!("successfully created subscription {subscription:?}");
    Ok(())
}

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

המדד 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 במקרים שבהם הבקשות מגיעות אל Cloud de Confiance by S3NS אבל לא מגיעות אל Pub/Sub. יש כשלים שהמדד הזה לא יתעד – למשל, כשהלקוחות מנותקים מ- Cloud de Confiance by S3NS.

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

מכסות

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

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

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

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

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

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

משלוח חד-פעמי מדויק ומינויים מסוג push

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

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

חשוב לדעת

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

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

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

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

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

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