push サブスクリプションを作成する

このドキュメントでは、push サブスクリプションを作成する方法について説明します。push サブスクリプションを作成するには、Trusted Cloud コンソール、Google Cloud CLI、クライアント ライブラリ、または Pub/Sub API を使用できます。

始める前に

必要なロールと権限

サブスクリプションを作成するには、プロジェクト レベルでアクセス制御を構成する必要があります。このセクションで後述するように、サブスクリプションとトピックが異なるプロジェクトにある場合は、リソースレベルの権限も必要です。

push サブスクリプションの作成に必要な権限を取得するには、管理者にプロジェクトに対する Pub/Sub 編集者 roles/pubsub.editor)IAM ロールを付与するよう依頼してください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

この事前定義ロールには、push サブスクリプションの作成に必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。

必要な権限

push サブスクリプションを作成するには、次の権限が必要です。

  • サブスクリプションを作成する: pubsub.subscriptions.create
  • サブスクリプションを削除する: pubsub.subscriptions.delete
  • サブスクリプションを取得する: pubsub.subscriptions.get
  • サブスクリプションを一覧表示する: pubsub.subscriptions.list
  • サブスクリプションを更新する: pubsub.subscriptions.update
  • サブスクリプションをトピックに接続する: pubsub.topics.attachSubscription
  • サブスクリプションの IAM ポリシーを取得する: pubsub.subscriptions.getIamPolicy
  • サブスクリプションの IAM ポリシーを構成する: pubsub.subscriptions.setIamPolicy

カスタムロールや他の事前定義ロールを使用して、これらの権限を取得することもできます。

別のプロジェクトのトピックに関連付けられているプロジェクトで push サブスクリプションを作成する必要がある場合は、トピック管理者にトピックに対する Pub/Sub 編集者の (roles/pubsub.editor) IAM ロールも付与するよう依頼してください。

push サブスクリプション プロパティ

push サブスクリプションを構成するときに、次のプロパティを指定できます。

共通の特徴

すべてのサブスクリプションで設定できる共通のサブスクリプション プロパティについて学習します。

エンドポイント

エンドポイント URL(必須)。一般公開されている HTTPS アドレス。push エンドポイントのサーバーには、認証局が署名した有効な SSL 証明書が必要です。Pub/Sub サービスでは、Pub/Sub サービスがメッセージを格納するのと同じ Trusted Cloud リージョンから push エンドポイントにメッセージを配信します。Pub/Sub サービスでは、同じ Trusted Cloud リージョンからベストエフォート方式でメッセージを配信します。

  • サブスクライバーがファイアウォールを使用している場合、push リクエストを受信できません。push リクエストを受信するには、ファイアウォールをオフにして、リクエストで使用されている JSON ウェブトークン(JWT)を検証する必要があります。購読者がファイアウォールを使用している場合、403 permission denied エラーが表示されることがあります。

  • Pub/Sub では、push サブスクリプションの URL ドメインの所有権の証明が不要になりました。ドメインが Pub/Sub からの予期しない POST リクエストを受信した場合は、不正行為を報告できます。

認証

認証を有効にする。有効にすると、Pub/Sub から push エンドポイントに配信されるメッセージには、エンドポイントでリクエストを認証できるようにする認可ヘッダーが含まれます。サブスクリプションと同じプロジェクトでホストされる App Engine Standard エンドポイントと Cloud Run functions エンドポイントでは、自動認証と自動承認のメカニズムを使用できます。

認証済み push サブスクリプションの認証構成は、ユーザーが管理するサービス アカウントと、createpatch または ModifyPushConfig 呼び出しで指定されるオーディエンス パラメータで構成されます。また、次のセクションで説明するように、サービス アカウントに特定のロールを付与する必要があります。

  • オーディエンス。Webhook が特定のトークンの対象オーディエンスの検証に使用する、大文字と小文字が区別されない単一の文字列。

  • サービス アカウント。Pub/Sub は、service-{PROJECT_NUMBER}@gcp-sa-pubsub.s3ns-system.iam.gserviceaccount.com 形式のサービス アカウントを自動的に作成します。

認証を有効にするための前提条件

ユーザー管理サービス アカウントは、push サブスクリプションに関連付けられているサービス アカウントです。このアカウントは、生成された JSON ウェブトークン(JWT)の email クレームとして使用されます。サービス アカウントの要件は次のとおりです。

  • このユーザー管理のサービス アカウントは、プッシュ サブスクリプションと同じプロジェクトに存在する必要があります。

  • push サブスクリプションを作成または変更するプリンシパルには、サービス アカウントを push サブスクリプションに関連付けるために、ユーザー管理のサービス アカウントに対する iam.serviceAccounts.actAs 権限が必要です。詳細については、サービス アカウントをリソースに関連付けるをご覧ください。

  • 必要な権限: このサービス アカウントには、Pub/Sub が指定されたサービス アカウントの JWT トークンを作成して push リクエストを認証できるように、iam.serviceAccounts.getOpenIdToken 権限(roles/iam.serviceAccountTokenCreator ロールに含まれる)が付与されている必要があります。

ペイロードのラップ解除

[ペイロードのラップ解除を有効にする] オプションでは、メッセージ データを除くすべてのメッセージ メタデータが Pub/Sub メッセージから削除されます。ペイロードのアンラップでは、メッセージ データが HTTP 本文として直接配信されます。

[メタデータの書き込み] オプションを有効にすることもできます。[メタデータを書き込む] オプションでは、以前に削除したメッセージ メタデータをリクエスト ヘッダーに追加します。

プライベート VPC アドレスに配信する

Pub/Sub は VPC ネットワークの外部で動作するため、プライベート VPC アドレスにメッセージを直接 push できません。ただし、Eventarc を使用して、VPC 内のサービスにメッセージを転送することはできます。Pub/Sub はメッセージを Eventarc トリガーに push できます。Eventarc トリガーは、Cloud Run サービスや Workflows 実行などの VPC 内のサービスにメッセージを転送できます。詳細については、Eventarc のドキュメントをご覧ください。

VPC Service Controls

VPC Service Controls で保護されているプロジェクトの場合、push サブスクリプションには次の制限があります。

  • push エンドポイントがデフォルトの run.app URL または Workflows の実行で Cloud Run サービスに設定されている新しい push サブスクリプションのみを作成できます。カスタム ドメインが機能しない。

  • push エンドポイントが Workflows 実行に設定されている Workflows の宛先に Eventarc を介してイベントをルーティングする場合、新しい push サブスクリプションは Eventarc を介してのみ作成できます。

  • 既存の push サブスクリプションを更新することはできません。これらの push サブスクリプションは引き続き機能しますが、VPC Service Controls による保護は受けられません。

push サブスクリプションを作成する

次のサンプルは、指定されたデフォルト設定を使用して、push 配信でサブスクリプションを作成する方法を示しています。

次の例に示すように、デフォルトでは、push 構成を明示的に設定しない限りサブスクリプションでは pull 配信を使用します。

Console

push サブスクリプションを作成する際の手順は、次のとおりです。

  1. Trusted Cloud コンソールで、[サブスクリプション] ページに移動します。

    サブスクリプションに移動

  2. [サブスクリプションを作成] をクリックします。
  3. [サブスクリプション ID] フィールドに名前を入力します。

    サブスクリプションの指定方法については、トピックまたはサブスクリプションの指定方法のガイドラインをご覧ください。

  4. プルダウン メニューからトピックを選択するか、作成します。サブスクリプションがトピックからメッセージを受信します。
  5. [配信タイプ] として [push] を選択します。
  6. エンドポイント URL を指定します。
  7. 他のすべてのデフォルト値は保持されます。
  8. [作成] をクリックします。

[トピック] セクションからサブスクリプションを作成することもできます。このショートカットは、トピックとサブスクリプションの関連付けに使用できます。

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

    [トピック] に移動

  2. サブスクリプションを作成するトピックの横の をクリックします。
  3. コンテキスト メニューから [サブスクリプションを作成] を選択します。
  4. [サブスクリプション ID] を入力します。

    サブスクリプションの指定方法については、トピックまたはサブスクリプションの指定方法のガイドラインをご覧ください。

  5. [配信タイプ] として [push] を選択します。
  6. エンドポイント URL を指定します。
  7. 他のすべてのデフォルト値は保持されます。
  8. [作成] をクリックします。

gcloud

  1. In the Trusted Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. push サブスクリプションを作成するには、gcloud pubsub subscriptions create コマンドを実行します。

    gcloud pubsub subscriptions create SUBSCRIPTION_ID \
    --topic=TOPIC_ID \
    --push-endpoint=PUSH_ENDPOINT

    次のように置き換えます。

    • SUBSCRIPTION_ID: 新しい push サブスクリプションの名前または ID。
    • TOPIC_ID: トピックの名前または ID。
    • PUSH_ENDPOINT: このサブスクリプションのエンドポイントとして使用する URL。例: https://myproject.appspot.com/myhandler
  3. REST

    push サブスクリプションを作成するには、projects.subscriptions.create メソッドを使用します。

    リクエスト:

    リクエストは、Authorization ヘッダー内のアクセス トークンにより認証を受ける必要があります。現在のアプリケーションのデフォルト認証情報のアクセス トークンを取得するには、gcloud auth application-default print-access-token を使用します。

    PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
    Authorization: Bearer ACCESS_TOKEN
    

    リクエスト本文:

    {
    "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
    // Only needed if you are using push delivery
    "pushConfig": {
    "pushEndpoint": "PUSH_ENDPOINT"
    }
    }

    ここで

  4. PROJECT_ID はプロジェクト ID です。
  5. SUBSCRIPTION_ID はサブスクリプション ID です。
  6. TOPIC_ID はトピック ID です。
  7. PUSH_ENDPOINT は、エンドポイントとして使用する URL です。例: https://myproject.appspot.com/myhandler
  8. レスポンス:

    {
    "name": "projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID",
    "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
    "pushConfig": {
    "pushEndpoint": "https://PROJECT_ID.appspot.com/myhandler",
    "attributes": {
      "x-goog-version": "v1"
    }
    },
    "ackDeadlineSeconds": 10,
    "messageRetentionDuration": "604800s",
    "expirationPolicy": {
    "ttl": "2678400s"
    }
    }

    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, std::string const& endpoint) {
      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.mutable_push_config()->set_push_endpoint(endpoint);
      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;
    
    public class CreatePushSubscriptionSample
    {
        public Subscription CreatePushSubscription(string projectId, string topicId, string subscriptionId, string pushEndpoint)
        {
            SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
            TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);
            SubscriptionName subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);
    
            PushConfig pushConfig = new PushConfig { PushEndpoint = pushEndpoint };
    
            // The approximate amount of time in seconds (on a best-effort basis) Pub/Sub waits for the
            // subscriber to acknowledge receipt before resending the message.
            var ackDeadlineSeconds = 60;
            var subscription = subscriber.CreateSubscription(subscriptionName, topicName, pushConfig, ackDeadlineSeconds);
            return subscription;
        }
    }

    Go

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

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

    import (
    	"context"
    	"fmt"
    	"io"
    
    	"cloud.google.com/go/pubsub/v2"
    	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
    )
    
    func createWithEndpoint(w io.Writer, projectID, topic, subscription, endpoint string) error {
    	// projectID := "my-project-id"
    	// topic := "projects/my-project-id/topics/my-topic"
    	// subscription := "projects/my-project/subscriptions/my-sub"
    	// endpoint := "https://my-test-project.appspot.com/push"
    	ctx := context.Background()
    	client, err := pubsub.NewClient(ctx, projectID)
    	if err != nil {
    		return fmt.Errorf("pubsub.NewClient: %w", err)
    	}
    	defer client.Close()
    
    	sub, err := client.SubscriptionAdminClient.CreateSubscription(ctx, &pubsubpb.Subscription{
    		Name:               subscription,
    		Topic:              topic,
    		AckDeadlineSeconds: 10,
    		PushConfig:         &pubsubpb.PushConfig{PushEndpoint: endpoint},
    	})
    	if err != nil {
    		return fmt.Errorf("failed to create push sub: %w", err)
    	}
    	fmt.Fprintf(w, "Created push subscription: %v\n", sub)
    	return nil
    }
    

    Java

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

    
    import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
    import com.google.pubsub.v1.PushConfig;
    import com.google.pubsub.v1.Subscription;
    import com.google.pubsub.v1.SubscriptionName;
    import com.google.pubsub.v1.TopicName;
    import java.io.IOException;
    
    public class CreatePushSubscriptionExample {
      public static void main(String... args) throws Exception {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String subscriptionId = "your-subscription-id";
        String topicId = "your-topic-id";
        String pushEndpoint = "https://my-test-project.appspot.com/push";
    
        createPushSubscriptionExample(projectId, subscriptionId, topicId, pushEndpoint);
      }
    
      public static void createPushSubscriptionExample(
          String projectId, String subscriptionId, String topicId, String pushEndpoint)
          throws IOException {
        try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
          TopicName topicName = TopicName.of(projectId, topicId);
          SubscriptionName subscriptionName = SubscriptionName.of(projectId, subscriptionId);
          PushConfig pushConfig = PushConfig.newBuilder().setPushEndpoint(pushEndpoint).build();
    
          // Create a push subscription with default acknowledgement deadline of 10 seconds.
          // Messages not successfully acknowledged within 10 seconds will get resent by the server.
          Subscription subscription =
              subscriptionAdminClient.createSubscription(subscriptionName, topicName, pushConfig, 10);
          System.out.println("Created push subscription: " + subscription.getName());
        }
      }
    }

    Node.js

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

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const pushEndpoint = 'YOUR_ENDPOINT_URL';
    // 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 createPushSubscription(
      pushEndpoint,
      topicNameOrId,
      subscriptionNameOrId,
    ) {
      const options = {
        pushConfig: {
          // Set to an HTTPS endpoint of your choice. If necessary, register
          // (authorize) the domain on which the server is hosted.
          pushEndpoint,
        },
      };
    
      await pubSubClient
        .topic(topicNameOrId)
        .createSubscription(subscriptionNameOrId, options);
      console.log(`Subscription ${subscriptionNameOrId} created.`);
    }

    Node.ts

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

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const pushEndpoint = 'YOUR_ENDPOINT_URL';
    // const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
    // const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
    
    // Imports the Google Cloud client library
    import {PubSub, CreateSubscriptionOptions} from '@google-cloud/pubsub';
    
    // Creates a client; cache this for further use
    const pubSubClient = new PubSub();
    
    async function createPushSubscription(
      pushEndpoint: string,
      topicNameOrId: string,
      subscriptionNameOrId: string,
    ) {
      const options: CreateSubscriptionOptions = {
        pushConfig: {
          // Set to an HTTPS endpoint of your choice. If necessary, register
          // (authorize) the domain on which the server is hosted.
          pushEndpoint,
        },
      };
    
      await pubSubClient
        .topic(topicNameOrId)
        .createSubscription(subscriptionNameOrId, options);
      console.log(`Subscription ${subscriptionNameOrId} created.`);
    }

    PHP

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

    use Google\Cloud\PubSub\PubSubClient;
    
    /**
     * Creates a Pub/Sub push subscription.
     *
     * @param string $projectId  The Google project ID.
     * @param string $topicName  The Pub/Sub topic name.
     * @param string $subscriptionName  The Pub/Sub subscription name.
     * @param string $endpoint  The endpoint for the push subscription.
     */
    function create_push_subscription($projectId, $topicName, $subscriptionName, $endpoint)
    {
        $pubsub = new PubSubClient([
            'projectId' => $projectId,
        ]);
        $topic = $pubsub->topic($topicName);
        $subscription = $topic->subscription($subscriptionName);
        $subscription->create([
            'pushConfig' => ['pushEndpoint' => $endpoint]
        ]);
    
        printf('Subscription created: %s' . PHP_EOL, $subscription->name());
    }

    Python

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

    from google.cloud import pubsub_v1
    
    # TODO(developer)
    # project_id = "your-project-id"
    # topic_id = "your-topic-id"
    # subscription_id = "your-subscription-id"
    # endpoint = "https://my-test-project.appspot.com/push"
    
    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)
    
    push_config = pubsub_v1.types.PushConfig(push_endpoint=endpoint)
    
    # Wrap the subscriber in a 'with' block to automatically call close() to
    # close the underlying gRPC channel when done.
    with subscriber:
        subscription = subscriber.create_subscription(
            request={
                "name": subscription_path,
                "topic": topic_path,
                "push_config": push_config,
            }
        )
    
    print(f"Push subscription created: {subscription}.")
    print(f"Endpoint for subscription is: {endpoint}")

    Ruby

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

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

    # topic_id          = "your-topic-id"
    # subscription_id   = "your-subscription-id"
    # endpoint          = "https://your-test-project.appspot.com/push"
    
    pubsub = Google::Cloud::PubSub.new
    subscription_admin = pubsub.subscription_admin
    
    subscription = subscription_admin.create_subscription \
      name: pubsub.subscription_path(subscription_id),
      topic: pubsub.topic_path(topic_id),
      push_config: {
        push_endpoint: endpoint
      }
    
    puts "Push subscription #{subscription_id} created."

push サブスクリプションをモニタリングする

Cloud Monitoring には、サブスクリプションをモニタリングするための指標が多数用意されています。

Pub/Sub に関連する使用可能なすべての指標のリストとその説明については、Pub/Sub のモニタリング ドキュメントをご覧ください。

Pub/Sub 内からサブスクリプションをモニタリングすることもできます。

次のステップ

  • gcloud コマンドを使用して、サブスクリプションを作成または変更する。
  • REST API を使用してサブスクリプションを作成または変更する。