메시지 순서 지정

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

이 페이지에서는 메시지를 순서대로 수신하는 방법에 대해 설명합니다.

메시지 수신에 대한 자세한 내용은 구독자 개요를 참조하세요.

순서대로 메시지 수신

메시지에 동일한 순서 키가 있으면서 리전이 동일한 경우 Pub/Sub 서비스에서 메시지를 수신하는 순서대로 메시지 순서를 사용할 수 있습니다.

Pub/Sub는 각 메시지를 최소 한 번은 전송하므로 Pub/Sub 서비스에서 메시지를 다시 전송할 수 있습니다. 순서대로 메시지를 수신하는 경우 Pub/Sub 서비스에서 순서 키가 포함된 메시지를 다시 전송할 때, Pub/Sub는 동일한 순서 키가 포함된 후속 메시지를 다시 전송하여 순서를 유지합니다. Pub/Sub 서비스는 최초에 받은 순서대로 이러한 메시지를 다시 전송합니다.

Pub/Sub 서비스에서 순서 키가 포함된 메시지를 다시 전송하는 경우 Pub/Sub 서비스는 확인된 메시지를 포함하여 동일한 순서 키로 모든 후속 메시지도 다시 전송합니다. 구독에서 메시지 순서 지정 및 데드 레터 주제가 모두 사용 설정된 경우, 가능한 경우 Pub/Sub가 메시지를 데드 레터 주제로 전달하기 때문에 그렇지 않을 수 있습니다. 재전송된 메시지가 수신되면 다시 메시지 수신을 확인해야 합니다. 이전 메시지가 확인되지 않은 상태에서 후속 메시지가 전송된다는 보장은 없습니다.

정렬된 키 및 메시지 전송

순서 키가 동일한 메시지는 순서대로 전송됩니다.

순서 키가 다른 메시지는 게시 시간과 관계없이 순서대로 전송됩니다.

메시지를 확인할 수 없게 되면 다른 순서 키의 메시지 전송을 보류할 수 있습니다. 이 문제는 서버가 예기치 않게 다시 시작되거나 트래픽 변경으로 인해 사용된 서버 집합에 변경사항이 있을 때 발생 가능합니다. 이러한 이벤트에서 순서를 보존하려면 순서 키가 다른 경우에도 새 서버의 메시지가 전송되기 전에 이전 서버에 게시된 모든 메시지를 확인해야 합니다. 모든 메시지를 적시에 확인할 수 없는 경우 구독에 데드 레터 주제를 연결하는 것이 좋습니다. 데드 레터 주제에 작성된 메시지 순서는 보존되지 않을 수 있습니다.

메시지 순서 사용 설정

메시지를 순서대로 받으려면 메시지를 수신하는 구독에서 메시지 순서 속성을 설정하세요. 메시지를 순서대로 수신하면 지연 시간이 늘어날 수 있습니다.

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub API를 사용하여 구독을 만들 때 메시지 순서 속성을 설정할 수 있습니다.

콘솔

메시지 순서 속성을 설정한 구독을 만들려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 구독 페이지로 이동합니다.

    구독 페이지로 이동

  2. 구독 만들기를 클릭합니다.

  3. 구독 ID를 입력합니다.

  4. 메시지를 받을 주제를 선택합니다.

  5. 메시지 순서 섹션에서 순서 키로 메시지 순서 지정을 선택합니다.

  6. 만들기를 클릭합니다.

gcloud

메시지 순서 속성을 설정한 구독을 만들려면 gcloud pubsub subscriptions create 명령어와 --enable-message-ordering 플래그를 사용합니다.

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --enable-message-ordering

SUBSCRIPTION_ID를 구독 ID로 바꿉니다.

요청이 성공하면 명령줄에 확인 메시지가 표시됩니다.

Created subscription [SUBSCRIPTION_ID].

REST

메시지 순서 속성을 설정하여 구독을 만들려면 다음과 같이 PUT 요청을 보냅니다.

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

다음을 바꿉니다.

  • PROJECT_ID: 주제가 있는 프로젝트의 프로젝트 ID
  • SUBSCRIPTION_ID: 구독의 ID

요청 본문에서 다음을 지정합니다.

{
  "topic": TOPIC_ID,
  "enableMessageOrdering": true,
}

TOPIC_ID를 구독에 연결할 주제의 ID로 바꿉니다.

요청이 성공하는 경우 응답은 JSON 형식의 구독입니다.

{
  "name": projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID,
  "topic": projects/PROJECT_ID/topics/TOPIC_ID,
  "enableMessageOrdering": true,
}

C++

이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 C++ 설정 안내를 따르세요. 자세한 내용은 Pub/Sub C++ API 참조 문서를 확인하세요.

namespace pubsub = ::google::cloud::pubsub;
[](pubsub::SubscriptionAdminClient client, std::string const& project_id,
   std::string const& topic_id, std::string const& subscription_id) {
  auto sub = client.CreateSubscription(
      pubsub::Topic(project_id, std::move(topic_id)),
      pubsub::Subscription(project_id, std::move(subscription_id)),
      pubsub::SubscriptionBuilder{}.enable_message_ordering(true));
  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 CreateSubscriptionWithOrderingSample
{
    public Subscription CreateSubscriptionWithOrdering(string projectId, string subscriptionId, string topicId)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        var topicName = TopicName.FromProjectTopic(projectId, topicId);
        var subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);

        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            EnableMessageOrdering = 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

이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Go 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Go API 참조 문서를 참조하세요.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/pubsub"
)

func createWithOrdering(w io.Writer, projectID, subID string, topic *pubsub.Topic) error {
	// projectID := "my-project-id"
	// subID := "my-sub"
	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %v", err)
	}
	defer client.Close()

	// Message ordering can only be set when creating a subscription.
	sub, err := client.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
		Topic:                 topic,
		AckDeadline:           20 * time.Second,
		EnableMessageOrdering: true,
	})
	if err != nil {
		return fmt.Errorf("CreateSubscription: %v", err)
	}
	fmt.Fprintf(w, "Created subscription: %v\n", sub)
	return nil
}

자바

이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 자바 설정 안내를 따르세요. 자세한 내용은 Pub/Sub 자바 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 CreateSubscriptionWithOrdering {
  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";

    createSubscriptionWithOrderingExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithOrderingExample(
      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())
                  // Set message ordering to true for ordered messages in the subscription.
                  .setEnableMessageOrdering(true)
                  .build());

      System.out.println("Created a subscription with ordering: " + subscription.getAllFields());
    }
  }
}

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 createSubscriptionWithOrdering(
  topicNameOrId,
  subscriptionNameOrId
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableMessageOrdering: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with ordering enabled.`
  );

  console.log(
    'To process messages in order, remember to add an ordering key to your messages.'
  );
}

Python

이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Python 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Python API 참조 문서를 참조하세요.

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_message_ordering": True,
        }
    )
    print(f"Created subscription with ordering: {subscription}")

Ruby

이 샘플을 시도하기 전에 빠른 시작: 클라이언트 라이브러리 사용의 Ruby 설정 안내를 따르세요. 자세한 내용은 Pub/Sub Ruby API 참조 문서를 참조하세요.

# topic_id        = "your-topic-id"
# subscription_id = "your-subscription-id"
require "google/cloud/pubsub"

pubsub = Google::Cloud::Pubsub.new

topic        = pubsub.topic topic_id
subscription = topic.subscribe subscription_id,
                               message_ordering: true

puts "Pull subscription #{subscription_id} created with message ordering."

메시지 순서 속성이 설정되면 Pub/Sub 서비스는 Pub/Sub 서비스에서 메시지를 수신하는 순서대로 동일한 순서 키가 포함된 메시지를 전송합니다. 예를 들어 게시자가 순서 키가 동일한 2개의 메시지를 보내면 Pub/Sub 서비스에서는 오래된 메시지를 먼저 전송합니다.

다음 단계

  • 정렬된 전송에 대한 블로그 게시물을 읽어보세요.

  • 구독을 모니터링합니다.

  • 순서 키를 사용하여 메시지 게시에 대해 알아봅니다.