メッセージのトピックへのパブリッシュ

このドキュメントでは、メッセージのパブリッシュについて説明します。

パブリッシャー アプリケーションによって、メッセージが作成され、トピックに送信されます。Pub/Sub では、既存のサブスクライバーに対して、メッセージの at-least-once 配信とベストエフォートの順序指定を実施しています。

パブリッシャー アプリケーションの一般的なフローは次のとおりです。

  1. データを含むメッセージを作成します。
  2. リクエストを Pub/Sub サーバーに送信し、指定されたトピックにメッセージをパブリッシュします。

始める前に

パブリッシュ ワークフローを構成する前に、次のタスクを完了していることを確認してください。

必要なロール

トピックにメッセージをパブリッシュするために必要な権限を取得するには、トピックに対する Pub/Sub パブリッシャー roles/pubsub.publisher)IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

トピックとサブスクリプションを作成または更新するには、追加の権限が必要です。

メッセージの形式

メッセージは、メッセージ データとメタデータを含むフィールドで構成されます。メッセージに少なくとも次のいずれかを指定します。

Pub/Sub サービスは、次のフィールドをメッセージに追加します。

  • トピックに一意のメッセージ ID
  • Pub/Sub サービスがメッセージを受信した時点のタイムスタンプ

メッセージの詳細については、メッセージ形式をご覧ください。

メッセージをパブリッシュする

メッセージは、 Google Cloud コンソール、Google Cloud CLI、Pub/Sub API、クライアント ライブラリを使用してパブリッシュできます。クライアント ライブラリは、メッセージを非同期的にパブリッシュできます。

次のサンプルは、メッセージをトピックにパブリッシュする方法を示しています。

Console

メッセージをパブリッシュする手順は次のとおりです。

  1. Google Cloud コンソールで、[Pub/Sub トピック] ページに移動します。

    Pub/Sub トピックページに移動

  2. トピック ID をクリックします。

  3. [トピックの詳細] ページの [メッセージ] で、[メッセージをパブリッシュ] をクリックします。

  4. [メッセージ本文] フィールドにメッセージのデータを入力します。

  5. [公開] をクリックします。

gcloud

メッセージをパブリッシュするには、gcloud pubsub topics publish コマンドを使用します。

gcloud pubsub topics publish TOPIC_ID \
  --message=MESSAGE_DATA \
  [--attribute=KEY="VALUE",...]

以下を置き換えます。

  • TOPIC_ID: トピックの ID
  • MESSAGE_DATA: メッセージ データを含む文字列
  • KEY: メッセージ属性のキー
  • VALUE: メッセージ属性のキーの値

REST

メッセージをパブリッシュするには、次のような POST リクエストを送信します。

POST  https://pubsub.googleapis.com/v1/projects/PROJECT_ID/topics/TOPIC_ID:publish
Content-Type: application/json
Authorization: Bearer $(gcloud auth application-default print-access-token)

以下を置き換えます。

  • PROJECT_ID: トピックがあるプロジェクトのプロジェクト ID
  • TOPIC_ID: トピックの ID

リクエスト本文に次のフィールドを指定します。

{
  "messages": [
    {
      "attributes": {
        "KEY": "VALUE",
        ...
      },
      "data": "MESSAGE_DATA",
    }
  ]
}

以下を置き換えます。

  • KEY: メッセージ属性のキー
  • VALUE: メッセージ属性のキーの値
  • MESSAGE_DATA: Base64 でエンコードされたメッセージ データの文字列

メッセージには、空でないデータ フィールドか、少なくとも 1 つの属性が含まれている必要があります。

リクエストが成功した場合のレスポンスは、メッセージ ID が含まれる JSON オブジェクトです。次の例は、メッセージ ID が含まれるレスポンスを示しています。

{
  "messageIds": [
    "19916711285",
  ]
}

C++

このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の C++ の設定手順を実施してください。詳細については、Pub/Sub C++ API リファレンス ドキュメントをご覧ください。

namespace pubsub = ::google::cloud::pubsub;
using ::google::cloud::future;
using ::google::cloud::StatusOr;
[](pubsub::Publisher publisher) {
  auto message_id = publisher.Publish(
      pubsub::MessageBuilder{}.SetData("Hello World!").Build());
  auto done = message_id.then([](future<StatusOr<std::string>> f) {
    auto id = f.get();
    if (!id) throw std::move(id).status();
    std::cout << "Hello World! published with id=" << *id << "\n";
  });
  // Block until the message is published
  done.get();
}

C#

このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の C# の設定手順を実施してください。詳細については、Pub/Sub C# API リファレンス ドキュメントをご覧ください。


using Google.Cloud.PubSub.V1;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public class PublishMessagesAsyncSample
{
    public async Task<int> PublishMessagesAsync(string projectId, string topicId, IEnumerable<string> messageTexts)
    {
        TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);
        PublisherClient publisher = await PublisherClient.CreateAsync(topicName);

        int publishedMessageCount = 0;
        var publishTasks = messageTexts.Select(async text =>
        {
            try
            {
                string message = await publisher.PublishAsync(text);
                Console.WriteLine($"Published message {message}");
                Interlocked.Increment(ref publishedMessageCount);
            }
            catch (Exception exception)
            {
                Console.WriteLine($"An error occurred when publishing message {text}: {exception.Message}");
            }
        });
        await Task.WhenAll(publishTasks);
        // PublisherClient instance should be shutdown after use.
        // The TimeSpan specifies for how long to attempt to publish locally queued messages.
        await publisher.ShutdownAsync(TimeSpan.FromSeconds(15));
        return publishedMessageCount;
    }
}

Go

次のサンプルでは、Go Pub/Sub クライアント ライブラリのメジャー バージョン(v2)を使用しています。v1 ライブラリをまだ使用している場合は、v2 への移行ガイドをご覧ください。v1 コードサンプルの一覧については、 非推奨のコードサンプルをご覧ください。

このサンプルを試す前に、クイックスタート: クライアント ライブラリの使用の Go の設定手順を実施してください。詳細については、Pub/Sub Go API のリファレンス ドキュメントをご覧ください。

import (
	"context"
	"fmt"
	"io"
	"strconv"
	"sync"
	"sync/atomic"

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

func publishThatScales(w io.Writer, projectID, topicID string, n int) error {
	// projectID := "my-project-id"
	// topicID := "my-topic"
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	var wg sync.WaitGroup
	var totalErrors uint64

	// client.Publisher can be passed a topic ID (e.g. "my-topic") or
	// a fully qualified name (e.g. "projects/my-project/topics/my-topic").
	// If a topic ID is provided, the project ID from the client is used.
	// Reuse this publisher for all publish calls to send messages in batches.
	publisher := client.Publisher(topicID)

	for i := 0; i < n; i++ {
		result := publisher.Publish(ctx, &pubsub.Message{
			Data: []byte("Message " + strconv.Itoa(i)),
		})

		wg.Add(1)
		go func(i int, res *pubsub.PublishResult) {
			defer wg.Done()
			// The Get method blocks until a server-generated ID or
			// an error is returned for the published message.
			id, err := res.Get(ctx)
			if err != nil {
				// Error handling code can be added here.
				fmt.Fprintf(w, "Failed to publish: %v", err)
				atomic.AddUint64(&totalErrors, 1)
				return
			}
			fmt.Fprintf(w, "Published message %d; msg ID: %v\n", i, id)
		}(i, result)
	}

	wg.Wait()

	if totalErrors > 0 {