卸離訂閱項目

建立訂閱項目時,您會將訂閱項目附加至主題,訂閱者即可從訂閱項目接收訊息。如要停止傳送訊息給訂閱者,可以將訂閱項目從主題卸離。

如要取消訂閱,您必須擁有主題的 pubsub.topics.detachSubscription 權限。您可以在沒有訂閱項目權限的情況下分離訂閱項目,這有助於管理與訂閱項目位於不同專案的主題。詳情請參閱 Pub/Sub 存取權控管

事前準備

必要角色和權限

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

這個預先定義角色具備分離及管理訂閱項目所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

如要取消連結及管理訂閱項目,必須具備下列權限:

  • 從訂閱項目提取: pubsub.subscriptions.consume
  • 建立訂閱項目: 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

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

您可以在專案層級和個別資源層級設定存取權控管。您可以在一個專案中建立訂閱項目,並將其附加至位於其他專案的主題。請確認您具備每個專案的必要權限。

將訂閱項目從主題卸離

您可以使用 Trusted Cloud 控制台、Google Cloud CLI、用戶端程式庫或 Pub/Sub API,將訂閱項目從主題中分離。

控制台

如要取消訂閱,請按照下列步驟操作:

  1. 前往 Trusted Cloud 控制台的「主題」頁面。

    前往「主題」

  2. 選取要取消訂閱的主題。

  3. 在「訂閱」分頁中,選取要取消連結的訂閱項目。

  4. 在「Subscription details」(訂閱詳細資料) 頁面中,按一下「Detach」(卸離)

  5. 在隨即顯示的對話方塊中,再次按一下「Detach」(取消連結)

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. 如要取消訂閱,請使用 gcloud pubsub topics detach-subscription 指令:

    gcloud pubsub topics detach-subscription SUBSCRIPTION_ID

    如果要求成功,指令列會顯示確認訊息:

    Detached subscription [SUBSCRIPTION_ID].
  3. REST

    如要取消連結訂閱項目,請使用 projects.subscriptions.detach 方法。

    要求:

    要求必須使用 Authorization 標頭中的存取權杖進行驗證。如要取得目前應用程式預設憑證的存取權杖,請使用 gcloud auth application-default print-access-token 指令。

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

    其中:

    • PROJECT_ID 是您的專案 ID。
    • SUBSCRIPTION_ID 是您的訂閱 ID。

    回應:

    如果要求成功,回應會是空白的 JSON 物件。

    C++

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

    namespace pubsub = ::google::cloud::pubsub;
    namespace pubsub_admin = ::google::cloud::pubsub_admin;
    [](pubsub_admin::TopicAdminClient client, std::string const& project_id,
       std::string const& subscription_id) {
      google::pubsub::v1::DetachSubscriptionRequest request;
      request.set_subscription(
          pubsub::Subscription(project_id, subscription_id).FullName());
      auto response = client.DetachSubscription(request);
      if (!response.ok()) throw std::move(response).status();
    
      std::cout << "The subscription was successfully detached: "
                << response->DebugString() << "\n";
    }

    C#

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

    
    using Google.Cloud.PubSub.V1;
    using System;
    
    public class DetachSubscriptionSample
    {
        public void DetachSubscription(string projectId, string subscriptionId)
        {
            PublisherServiceApiClient publisher = PublisherServiceApiClient.Create();
    
            DetachSubscriptionRequest detachSubscriptionRequest = new DetachSubscriptionRequest
            {
                SubscriptionAsSubscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId),
            };
    
            publisher.DetachSubscription(detachSubscriptionRequest);
    
            Console.WriteLine($"Subscription {subscriptionId} is detached.");
        }
    }

    Go

    以下範例使用 Go Pub/Sub 用戶端程式庫的主要版本 (v2)。如果您仍在使用第 1 版程式庫,請參閱第 2 版遷移指南。如要查看第 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 detachSubscription(w io.Writer, projectID, subName string) error {
    	// projectID is the project which contains the topic you manage.
    	// This might differ from the project which contains the subscription
    	// you wish to detach, which can exist in any GCP project.
    	// projectID := "my-project-id"
    	// subName := "projects/some-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()
    
    	// Call DetachSubscription, which detaches a subscription from
    	// a topic. This can only be done if you have the
    	// `pubsub.topics.detachSubscription` role on the topic the
    	// subscription is attached to.
    	req := &pubsubpb.DetachSubscriptionRequest{
    		Subscription: subName,
    	}
    	_, err = client.TopicAdminClient.DetachSubscription(ctx, req)
    	if err != nil {
    		return fmt.Errorf("detach subscription failed: %w", err)
    	}
    
    	fmt.Fprintf(w, "Detached subscription %s", subName)
    	return nil
    }
    

    Java

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

    import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
    import com.google.cloud.pubsub.v1.TopicAdminClient;
    import com.google.pubsub.v1.DetachSubscriptionRequest;
    import com.google.pubsub.v1.Subscription;
    import com.google.pubsub.v1.SubscriptionName;
    import java.io.IOException;
    
    public class DetachSubscriptionExample {
      public static void main(String... args) throws Exception {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        // Choose an existing subscription.
        String subscriptionId = "your-subscription-id";
    
        detachSubscriptionExample(projectId, subscriptionId);
      }
    
      public static void detachSubscriptionExample(String projectId, String subscriptionId)
          throws IOException {
        SubscriptionName subscriptionName = SubscriptionName.of(projectId, subscriptionId);
    
        try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
          topicAdminClient.detachSubscription(
              DetachSubscriptionRequest.newBuilder()
                  .setSubscription(subscriptionName.toString())
                  .build());
        }
    
        try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
          Subscription subscription = subscriptionAdminClient.getSubscription(subscriptionName);
          if (subscription.getDetached()) {
            System.out.println("Subscription is detached.");
          } else {
            System.out.println("Subscription is NOT detached.");
          }
        }
      }
    }

    Node.js

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

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const subscriptionNameOrId = 'YOUR_EXISTING_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 detachSubscription(subscriptionNameOrId) {
      // Gets the status of the existing subscription
      const sub = pubSubClient.subscription(subscriptionNameOrId);
      const [detached] = await sub.detached();
      console.log(
        `Subscription ${subscriptionNameOrId} 'before' detached status: ${detached}`,
      );
    
      await pubSubClient.detachSubscription(subscriptionNameOrId);
      console.log(`Subscription ${subscriptionNameOrId} detach request was sent.`);
    
      const [updatedDetached] = await sub.detached();
      console.log(
        `Subscription ${subscriptionNameOrId} 'after' detached status: ${updatedDetached}`,
      );
    }

    Node.ts

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

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const subscriptionNameOrId = 'YOUR_EXISTING_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 detachSubscription(subscriptionNameOrId: string) {
      // Gets the status of the existing subscription
      const sub = pubSubClient.subscription(subscriptionNameOrId);
      const [detached] = await sub.detached();
      console.log(
        `Subscription ${subscriptionNameOrId} 'before' detached status: ${detached}`,
      );
    
      await pubSubClient.detachSubscription(subscriptionNameOrId);
      console.log(`Subscription ${subscriptionNameOrId} detach request was sent.`);
    
      const [updatedDetached] = await sub.detached();
      console.log(
        `Subscription ${subscriptionNameOrId} 'after' detached status: ${updatedDetached}`,
      );
    }

    PHP

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

    use Google\Cloud\PubSub\PubSubClient;
    
    /**
     * Detach a Pub/Sub subscription from a topic.
     *
     * @param string $projectId  The Google project ID.
     * @param string $subscriptionName  The Pub/Sub subscription name.
     */
    function detach_subscription($projectId, $subscriptionName)
    {
        $pubsub = new PubSubClient([
            'projectId' => $projectId,
        ]);
        $subscription = $pubsub->subscription($subscriptionName);
        $subscription->detach();
    
        printf('Subscription detached: %s' . PHP_EOL, $subscription->name());
    }

    Python

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

    from google.api_core.exceptions import GoogleAPICallError, RetryError
    from google.cloud import pubsub_v1
    
    # TODO(developer): Choose an existing subscription.
    # project_id = "your-project-id"
    # subscription_id = "your-subscription-id"
    
    publisher_client = pubsub_v1.PublisherClient()
    subscriber_client = pubsub_v1.SubscriberClient()
    subscription_path = subscriber_client.subscription_path(project_id, subscription_id)
    
    try:
        publisher_client.detach_subscription(
            request={"subscription": subscription_path}
        )
    except (GoogleAPICallError, RetryError, ValueError, Exception) as err:
        print(err)
    
    subscription = subscriber_client.get_subscription(
        request={"subscription": subscription_path}
    )
    if subscription.detached:
        print(f"{subscription_path} is detached.")
    else:
        print(f"{subscription_path} is NOT detached.")

    Ruby

    以下範例使用 Ruby Pub/Sub 用戶端程式庫 v3。如果您仍在使用第 2 版程式庫,請參閱 第 3 版遷移指南。如要查看 Ruby 第 2 版程式碼範例清單,請參閱 已淘汰的程式碼範例

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

    # subscription_id = "your-subscription-id"
    
    pubsub = Google::Cloud::PubSub.new
    topic_admin = pubsub.topic_admin
    subscription_admin = pubsub.subscription_admin
    subscription_path = pubsub.subscription_path subscription_id
    
    topic_admin.detach_subscription subscription: subscription_path
    sleep 120
    subscription = subscription_admin.get_subscription \
      subscription: subscription_path
    
    if subscription.detached
      puts "Subscription is detached."
    else
      puts "Subscription is NOT detached."
    end

Pub/Sub 服務可能需要幾分鐘才能完成將訂閱項目從主題中分離。

Pub/Sub 服務將訂閱項目從主題中分離後,就會刪除為該訂閱項目保留的所有訊息。您無法從訂閱項目擷取這些訊息,也無法將訂閱項目重新附加至主題。如要釋出 Trusted Cloud 專案配額,請刪除訂閱項目

如果訂閱項目和主題位於不同 Trusted Cloud 專案,Pub/Sub 服務會在兩個專案的稽核記錄中新增項目。

後續步驟