建立推送訂閱項目

本文將說明如何建立推播訂閱。您可以使用Google Cloud 控制台、Google Cloud CLI、用戶端程式庫或 Pub/Sub API 建立推播訂閱項目。

事前準備

必要角色和權限

如要建立訂閱項目,您必須在專案層級設定存取權控管。如果訂閱項目和主題位於不同專案中,您也需要資源層級權限,請參閱本節後續的說明。

如要取得建立推播訂閱所需的權限,請要求管理員為您授予專案的 Pub/Sub 編輯者 (roles/pubsub.editor) 身分與存取權管理角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

這個預先定義的角色包含建立推播訂閱所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

如要建立推播訂閱項目,您必須具備下列權限:

  • 建立訂閱項目: pubsub.subscriptions.create
  • 刪除訂閱項目: pubsub.subscriptions.delete
  • 取得訂閱項目: pubsub.subscriptions.get
  • 列出訂閱項目: pubsub.subscriptions.list
  • 更新訂閱: pubsub.subscriptions.update
  • 將訂閱項目附加至主題: pubsub.topics.attachSubscription
  • 取得訂閱項目的身分與存取權管理政策: pubsub.subscriptions.getIamPolicy
  • 設定訂閱項目的 IAM 政策 pubsub.subscriptions.setIamPolicy

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

如果您需要在一個專案中建立與另一個專案主題相關的推播訂閱項目,請要求主題管理員也將 Pub/Sub 編輯者 (roles/pubsub.editor) IAM 角色授予您。

推送訂閱屬性

設定推送訂閱時,您可以指定下列屬性。

常見屬性

瞭解您可以在所有訂閱項目中設定的常見訂閱屬性

端點

端點網址 (必要)。可公開存取的 HTTPS 位址。推送端點的伺服器必須具備由憑證授權單位簽署的有效 SSL 憑證。Pub/Sub 服務會將訊息傳送至推送端點,且該端點位於 Pub/Sub 服務儲存訊息的 Google Cloud 區域。Pub/Sub 服務會盡力傳送來自相同 Google Cloud 區域的訊息。

Pub/Sub 不再要求推送訂閱項目網址網域的擁有權證明。如果您的網域收到來自 Pub/Sub 的不明 POST 要求,您可以回報疑似濫用行為

驗證

啟用驗證功能。啟用後,Pub/Sub 傳送至推送端點的訊息會包含授權標頭,讓端點能夠驗證要求。與訂閱項目一起託管在相同專案中的 App Engine 標準和 Cloud Run 函式端點,都可以使用自動驗證和授權機制。

經過驗證的推送訂閱項目的驗證設定包含使用者管理的服務帳戶,以及在 createpatchModifyPushConfig 呼叫中指定的目標對象參數。您也必須為服務帳戶授予特定角色,如下一節所述。

  • 目標對象。一個不區分大小寫的字串,可供 Webhook 驗證這個特定符記的目標對象。

  • 服務帳戶。Pub/Sub 會自動為您建立服務帳戶,格式為 service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com

啟用驗證功能的必要條件

使用者管理的服務帳戶是與推送訂閱項目相關聯的服務帳戶。這個帳戶會用於產生的 JSON Web Token (JWT) 的 email 憑證附加資訊。以下列出服務帳戶的相關規定:

酬載解除包裝

「啟用酬載解除包裝」選項會移除 Pub/Sub 訊息的所有訊息中繼資料,但訊息資料除外。透過酬載展開,訊息資料會直接以 HTTP 主體的形式傳送。

您也可以啟用「Write metadata」選項。「Write metadata」選項會將先前移除的訊息中繼資料重新加入要求標頭。

將內容傳送至私人 VPC 位址

Pub/Sub 會在虛擬私有雲網路外運作,無法直接將訊息推送至私人 VPC 位址。不過,您可以使用 Eventarc 將訊息轉送至 VPC 內的服務。Pub/Sub 可將訊息推送至 Eventarc 觸發事件,然後再將訊息轉送至虛擬私有雲中的服務,例如 Cloud Run 服務或工作流程執行作業。詳情請參閱 Eventarc 說明文件

VPC Service Controls

對於受到 VPC Service Controls 保護的專案,請注意推播訂閱的以下限制:

  • 您只能建立新的推送訂閱,且推送端點必須設為使用預設 run.app 網址或 Workflows 執行作業的 Cloud Run 服務。自訂網域無法運作。

  • 如果透過 Eventarc 將事件轉送至推播端點設為 Workflows 執行的 Workflows 目的地,您只能透過 Eventarc 建立新的推播訂閱項目。

  • 您無法更新現有的推播訂閱。這些推送訂閱將繼續運作,不過將不會受到 VPC Service Controls 保護。

建立推送訂閱項目

以下範例示範如何使用提供的預設設定,建立使用推播提交的訂閱項目。

根據預設,訂閱會使用提取提交,除非您明確設定推送設定,如以下範例所示。

控制台

如要建立推播訂閱,請完成下列步驟:

  1. 在 Google Cloud 控制台中,前往「訂閱項目」頁面。

    前往「訂閱項目」頁面

  2. 按一下「Create Subscription」 (建立訂閱項目)
  3. 在「Subscription ID」欄位中輸入名稱。

    如要瞭解如何命名訂閱項目,請參閱「命名主題或訂閱項目的規範」。

  4. 從下拉式選單中選擇或建立主題。訂閱項目會接收主題的訊息。
  5. 將「傳送類型」設為「推送」
  6. 指定端點網址。
  7. 保留所有其他預設值。
  8. 按一下 [建立]。

您也可以透過「主題」部分建立訂閱項目。這個快捷動作可用於將主題與訂閱項目建立關聯。

  1. 前往 Google Cloud 控制台的「Topics」頁面。

    前往「主題」

  2. 按一下要建立訂閱的主題旁邊的
  3. 在內容選單中,選取「建立訂閱」
  4. 輸入「Subscription ID」(訂閱 ID)

    如要瞭解如何命名訂閱項目,請參閱「命名主題或訂閱項目的規範」。

  5. 將「傳送類型」設為「推送」
  6. 指定端點網址。
  7. 保留所有其他預設值。
  8. 按一下 [建立]。

gcloud

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

    Activate Cloud Shell

    At the bottom of the Google 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. 如要建立推播訂閱項目,請執行 gcloud pubsub subscriptions create 指令。

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

    更改下列內容:

    • SUBSCRIPTION_ID:新推播訂閱項目的名稱或 ID。
    • TOPIC_ID:主題的名稱或 ID。
    • PUSH_ENDPOINT:要用來做為此訂閱項目端點的網址。例如:https://myproject.appspot.com/myhandler

REST

如要建立推送訂閱項目,請使用 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"
  }
}

其中:

  • PROJECT_ID 是您的專案 ID。
  • SUBSCRIPTION_ID 是訂閱項目 ID。
  • TOPIC_ID 是主題 ID。
  • PUSH_ENDPOINT 是用於做為端點的網址。例如:https://myproject.appspot.com/myhandler
  • 回應:

    {
      "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#

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 C#。詳情請參閱 Pub/Sub C# API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    
    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

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 Go。詳情請參閱 Pub/Sub Go API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	"cloud.google.com/go/pubsub"
    )
    
    func createWithEndpoint(w io.Writer, projectID, subID string, topic *pubsub.Topic, endpoint string) error {
    	// projectID := "my-project-id"
    	// subID := "my-sub"
    	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
    	// 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.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
    		Topic:       topic,
    		AckDeadline: 10 * time.Second,
    		PushConfig:  pubsub.PushConfig{Endpoint: endpoint},
    	})
    	if err != nil {
    		return fmt.Errorf("CreateSubscription: %w", err)
    	}
    	fmt.Fprintf(w, "Created push subscription: %v\n", sub)
    	return nil
    }
    

    Java

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 Java。詳情請參閱 Pub/Sub Java API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    
    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

    /**
     * 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.js

    /**
     * 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

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 PHP。詳情請參閱 Pub/Sub PHP API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    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

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 Python。詳情請參閱 Pub/Sub Python API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    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

    在嘗試這個範例之前,請先按照 Pub/Sub 快速入門:使用用戶端程式庫中的操作說明設定 Ruby。詳情請參閱 Pub/Sub Ruby API 參考說明文件

    如要向 Pub/Sub 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

    # topic_id          = "your-topic-id"
    # subscription_id   = "your-subscription-id"
    # endpoint          = "https://your-test-project.appspot.com/push"
    
    pubsub = Google::Cloud::Pubsub.new
    
    topic        = pubsub.topic topic_id
    subscription = topic.subscribe subscription_id,
                                   endpoint: endpoint
    
    puts "Push subscription #{subscription_id} created."

    監控推送訂閱

    Cloud Monitoring 提供多項指標,可用於監控訂閱項目

    如需 Pub/Sub 相關指標的完整清單和說明,請參閱 Pub/Sub 監控說明文件

    您也可以在 Pub/Sub 中監控訂閱項目。

    後續步驟