LoginSignup
11
11

More than 3 years have passed since last update.

GCP - Pub/Sub サービス概要

Last updated at Posted at 2020-05-19

GCPのPub/Subサービスの概要をまとめました。

概要

メッセージの受け渡しと非同期統合を実装するサービス。
同様のサービスにCloud Tasksがあるがそれぞれ異なる一連のユースケースを対象に設計されています。
どちらを選択するかは「Cloud Tasks か Pub/Sub かの選択」を参考に各自のユースケースに照らし合わせて選択するとよい。

pull 配信または push 配

サブスクリプションでは、メッセージ配信に push または pull のメカニズムを使用できます。このメカニズムは、いつでも変更または構成できます。

pull サブスクリプション

pull 配信では、サブスクライバー アプリケーションが Pub/Sub サーバーに対してリクエストを開始し、メッセージを取得します。

  1. サブスクライブしているアプリケーションは、メッセージの配信をリクエストする pull メソッドを明示的に呼び出します。
  2. Pub/Sub サーバーはメッセージ(キューが空の場合はエラー)と確認応答 ID で応答します。
  3. サブスクライバーは戻された確認応答 ID を使用して acknowledge メソッドを明示的に呼び出し、受信を確認します。

push サブスクリプション

push 配信1では、Pub/Sub がサブスクライバー アプリケーションに対してリクエストを開始し、メッセージを配信します。
1. Pub/Sub サーバーは、事前構成されたエンドポイントで、サブスクライバー アプリケーションに各メッセージを HTTPS リクエストとして送信します。
2. エンドポイントは、HTTP 成功ステータス コードを返すことでメッセージに確認応答します。不成功のレスポンスは、メッセージを再送信する必要があることを示します。

pull配信とpush配信の選択のガイドライン

pull配信
  • メッセージが多い場合(1 秒間に 1 個超)
  • メッセージ処理の効率とスループットが重要
  • 非自己署名 SSL 証明書を持つパブリック HTTPS エンドポイントの設定が現実的ではない場合
push配信
  • 同じ webhook で処理する必要がある複数のトピック
  • App Engine スタンダードおよび Cloud Functions のサブスクライバー
  • Google Cloud の依存関係(認証情報やクライアント ライブラリ)が設定できない環境

Cloud Pub/Sub 認証

サービス アカウント

ローカルの開発でも本番環境のアプリケーションでも、ほとんどのユースケースでサービス アカウントの使用が推奨されている。
App Engineから利用するのであればApp Engineのサービスアカウントが利用されるので適切なロールを紐づけてあげる必要がある。

認証情報の自動検出

Google Cloud クライアント ライブラリでは、アプリケーションのデフォルト認証情報(ADC)を使用してアプリケーションの認証情報を検出する

デフォルト認証情報(ADC)
  1. 環境変数GOOGLE_APPLICATION_CREDENTIALS の設定値で確認
  2. サービスで実行されているアプリケーションに応じて、Compute EngineGoogle Kubernetes EngineCloud RunApp EngineCloud Functions によって提供されているデフォルトのサービス アカウントを使用
App Engine スタンダード環境での認証情報の取得

アプリケーションが App Engine スタンダード環境で実行されている場合、App Engine App Identity API を使用して認証情報を取得できる。

アクセス制御

Pub/Sub では、アクセス制御に Cloud Identity and Access Management(Cloud IAM)を使用する。

Pub/Sub では、アクセス制御をプロジェクト レベルと個々のリソースレベルで構成できます。
以下例:

  • Cloud プロジェクト全体ではなく、トピックごと、またはサブスクリプションごとにアクセス権を付与します。
  • 機能が限定されたアクセス権を付与します。たとえば、トピックにメッセージをパブリッシュするのみのアクセス権、サブスクリプションからのメッセージを使用するのみで、トピックやサブスクリプションを削除できないアクセス権などです。
  • プロジェクト内のすべての Pub/Sub リソースに対するアクセス権限を、デベロッパーのグループに付与します。

権限と役割

ロール
ロール 権限 リソールタイプ
roles/pubsub.publisher pubsub.topics.publish トピック
roles/pubsub.subscriber pubsub.snapshots.seek スナップショット
pubsub.subscriptions.consume サブスクリプション
pubsub.topics.attachSubscription トピック
roles/pubsub.viewer またはroles/viewer 上記すべてと下記の権限
pubsub.snapshots.get スナップショット
pubsub.snapshots.list プロジェクト
pubsub.subscriptions.get サブスクリプション
pubsub.subscriptions.list プロジェクト
pubsub.topics.get トピック
pubsub.topics.list プロジェクト
resourcemanager.projects.get プロジェクト
servicemanagement.projectSettings.get プロジェクト
serviceusage.quotas.get プロジェクト
serviceusage.services.get プロジェクト
serviceusage.services.list プロジェクト
roles/pubsub.editor またはroles/editor 上記すべてと下記の権限
       スナップショットのCRUDに関する権限 スナップショット
       サブスクリプションのCRUDに関する権限 サブスクリプション
       トピックのCRUDに関する権限 トピック
roles/pubsub.admin またはroles/owner 上記すべてと下記の権限
       スナップショットのiamポリシーの取得と設定権限 スナップショット
       サブスクリプションのiamポリシーの取得と設定権限 サブスクリプション
       トピックののiamポリシーの取得と設定権限 トピック

ポリシーについて

Google Cloud リソースのアクセス制御は、Cloud IAM ポリシーによって管理されます。Cloud IAM ポリシーはリソースに関連付けられます。
このポリシーは、そのリソース自体へのアクセスだけでなく、ポリシーの継承により、子リソースへのアクセスも管理します。

ポリシーの構造

ポリシーは、バインディング、監査構成、メタデータから構成される。

  • バインディング : リソースへのアクセス権を付与する方法を指定し1 つ以上のメンバーを 1 つのロールに関連付けて(バインディング)、コンテキスト固有の条件を適用
  • 監査構成 : AuditConfig フィールドには、アクセス監査の構成データを指定
  • メタデータ : メタデータには、Etag やバージョンなど、ポリシーに関する追加情報を記述
バインディングのリスト

各バインディングは次のフィールドで構成されます。

  • メンバー : ID またはプリンシパルともいいます。ユーザー アカウント、サービス アカウント、Google グループ、ドメインなどがメンバーになります。
  • ロール : Google Cloud リソースに対してアクションを実行するための権限をまとめたものです。
  • 条件 : リクエストの属性(リクエストの送信元、ターゲット リソースなど)に基づいてロールのバインディングをさらに制限する論理式です。条件は通常、アクセスがリクエストされたときのコンテキストに応じて制限を行う場合に使用します。
AuditConfig フィールド

ポリシーの監査ロギングを構成するときに使用します。

メタデータ

次のフィールドがあります。

  • etag フィールド : 同時制御に使用し、ポリシーが一貫した方法で更新されるようにします。
  • version フィールド : 特定のポリシーのスキーマ バージョンを指定します。

例: 条件付きロール バインディングを含むポリシー

{
      "bindings": [
        {
          "members": [
            "group:prod-dev@example.com",
            "serviceAccount:prod-dev-example@appspot.gserviceaccount.com"
          ],
          "role": "roles/appengine.Deployer",
          "condition": {
              "title": "Expires_July_1_2020",
              "description": "Expires on July 1, 2020",
              "expression":
                "request.time < timestamp('2020-07-01T00:00:00.000Z')"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }

トピックとサブスクリプションの管理

Pub/Sub のトピックとサブスクリプションを作成、削除、管理

トピックの管理

トピックの作成

CLI

gcloud pubsub topics create myTopic

Python

topic.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"

    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(project_id, topic_name)

    topic = publisher.create_topic(topic_path)

    print("Topic created: {}".format(topic))

トピックの削除

トピックを削除しても、サブスクリプションは削除されません。サブスクライバーは、サブスクリプションのメッセージ バックログを使用できます。トピックが削除されると、そのサブスクリプションのトピック名は deleted-topic になります。トピックを削除した直後に同名のトピックを新規作成しようとすると、エラーが発生します。
CLI

gcloud pubsub topics delete myTopic

Python

topic.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"

    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(project_id, topic_name)

    publisher.delete_topic(topic_path)

    print("Topic deleted: {}".format(topic_path))

トピックの一覧表示

デフォルトでは、クエリあたり最大で 100 件の結果が返されます。 ページサイズ パラメータを使用すると、最大で 1,000 までの代替値を指定できます。
CLI

gcloud pubsub topics list

Python

topic.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"

    publisher = pubsub_v1.PublisherClient()
    project_path = publisher.project_path(project_id)

    for topic in publisher.list_topics(project_path):
        print(topic)

サブスクリプションの管理

サブスクリプションの作成

デフォルトでは、サブスクリプションは pull 配信を使用します。
CLI

gcloud pubsub subscriptions create SUBSCRIPTION_ID
      --topic=TOPIC_ID
      [--ack-deadline=ACK_DEADLINE]
      [--message-retention-duration=MESSAGE_RETENTION_DURATION]
      [--expiration-period=EXPIRATION_PERIOD]
      [--push-endpoint=PUSH_ENDPOINT]

Python

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"
    # TODO subscription_name = "Your Pub/Sub subscription name"

    subscriber = pubsub_v1.SubscriberClient()
    topic_path = subscriber.topic_path(project_id, topic_name)
    subscription_path = subscriber.subscription_path(
        project_id, subscription_name
    )

    subscription = subscriber.create_subscription(
        subscription_path, topic_path
    )

    print("Subscription created: {}".format(subscription))

    subscriber.close()

次のサンプルは、push 配信でサブスクリプションを作成する方法を示しています。

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"
    # TODO subscription_name = "Your Pub/Sub subscription name"
    # TODO endpoint = "https://my-test-project.appspot.com/push"

    subscriber = pubsub_v1.SubscriberClient()
    topic_path = subscriber.topic_path(project_id, topic_name)
    subscription_path = subscriber.subscription_path(
        project_id, subscription_name
    )

    push_config = pubsub_v1.types.PushConfig(push_endpoint=endpoint)

    subscription = subscriber.create_subscription(
        subscription_path, topic_path, push_config
    )

    print("Push subscription created: {}".format(subscription))
    print("Endpoint for subscription is: {}".format(endpoint))

    subscriber.close()

サブスクリプション プロパティの使用

サブスクリプション プロパティは、サブスクリプションを作成または更新するときに設定できます。

配信方法の変更

Cloud Console、gcloud コマンドライン ツール、Cloud Pub/Sub API のいずれかを使用して、push サブスクリプションと pull サブスクリプションを切り替えることができます。

サブスクリプションで pull 配信がすでに使用されている場合、push エンドポイントを設定すると配信方法がプッシュ push 配信に切り替わります。
push エンドポイントを空の文字列に変更すると、push 配信から pull 配信に切り替えることができます。
CLI

gcloud pubsub subscriptions modify-push-config SUBSCRIPTION_ID
  --push-endpoint=PUSH_ENDPOINT

Python

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"
    # TODO subscription_name = "Your Pub/Sub subscription name"
    # TODO endpoint = "https://my-test-project.appspot.com/push"

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_name
    )

    push_config = pubsub_v1.types.PushConfig(push_endpoint=endpoint)

    subscription = pubsub_v1.types.Subscription(
        name=subscription_path, push_config=push_config
    )

    update_mask = {"paths": {"push_config"}}
    subscriber.update_subscription(subscription, update_mask)
    result = subscriber.get_subscription(subscription_path)

    print("Subscription updated: {}".format(subscription_path))
    print("New endpoint for subscription is: {}".format(result.push_config))

    subscriber.close()

サブスクリプションの一覧表示

CLI

# Project > Subscription list
gcloud pubsub subscriptions list [--project=PROJECT_ID]

# Project > Topic > Subscription list
gcloud pubsub topics list-subscriptions TOPIC_ID 

Python : Project > Subscription list

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"

    subscriber = pubsub_v1.SubscriberClient()
    project_path = subscriber.project_path(project_id)

    for subscription in subscriber.list_subscriptions(project_path):
        print(subscription.name)

    subscriber.close()

Python : Project > Topic > Subscription list

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO topic_name = "Your Pub/Sub topic name"

    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(project_id, topic_name)

    for subscription in publisher.list_topic_subscriptions(topic_path):
        print(subscription)

サブスクリプションを削除する

CLI

gcloud pubsub subscriptions delete SUBSCRIPTION_ID

Python

subscription.py
from google.cloud import pubsub_v1

    # TODO project_id = "Your Google Cloud Project ID"
    # TODO subscription_name = "Your Pub/Sub subscription name"

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_name
    )

    subscriber.delete_subscription(subscription_path)

    print("Subscription deleted: {}".format(subscription_path))

    subscriber.close()

リソース名

Pub/Sub リソース名は、サブスクリプションやトピックなどの Pub/Sub のリソースを一意に識別します。

GCP - Pub/Sub サービス構築チュートリアルへ続きます


  1. 注: VPC Service Controls で保護されているプロジェクトでは、push サブスクリプションを新規作成できません。既存の push サブスクリプションは引き続き機能しますが、VPC Service Controls による保護は受けられません。 

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11