Cloud Pub/Subを使ったMessageのPublishとSubscribe

GCPのCloud Pub/Subを使ってMessageのPulishとSubscribeをしてみる。

Cloud PubSubについては以下の公式ページに記載されている。
https://cloud.google.com/pubsub/overview
意訳したものを以下にまとめる。図などは公式ページから引用。

Cloud Pub/Subはスケーラブルでフレキシブル、そして信頼性のあるエンタープライズのメッセージングミドルウェア。多対多の非同期メッセージグングによってセキュアで高可用性のあるアプリケーションを開発できる。
パブリッシャーアプリケーションはメッセージを作成しTopicへメッセージを送信する。
サブスクライバーアプリケーションはTopicからメッセージを取得するためにサブスクリプションを作成する。
1対多や多対1、多対多のコミュニケーションが可能である。

![many-to-many.png](https://qiita-image-store.s3.amazonaws.com/0/95399/dc876728-2d0d-f760-9392-adb6c8875ca0.png)

Pub/Subのメッセージの流れは下図のとおりである。
![pub_sub_flow.png](https://qiita-image-store.s3.amazonaws.com/0/95399/c2671e5d-8250-67cd-2e4b-27f0124fce65.png)

1. パブリッシャーアプリケーションはトピックを生成し、トピックへメッセージを送信する。メッセージはペイロードとオプションの属性を含む。
2. メッセージはサブスクライバーからackが返されるまでmessage storeに保管される。
3. Pub/Subサービスはトピックからのメッセージを各サブスクリプションにフォワードする。各サブスクリプションはメッセージをPub/SubからのPushもしくはサブスクライバーからのPullでメッセージを受取る。
4. サブスクライバーはメッセージを受取り、ackをPub/Subサービスへ返す
5. サブスクライバーからackが返されると、メッセージキューからメッセージが削除される。

# メッセージの登録、取得、削除
Pub/SubのAPIは以下を参照
https://cloud.google.com/sdk/gcloud/reference/alpha/pubsub/

### メッセージの登録

```
$ sudo gcloud components install alpha
$ sudo gcloud components install pubsub-emulator
```
GCPコンソール経由でCloud Pub/Subのトピックページにアクセスし、 トピックを作成する。

```
$ gcloud alpha pubsub topics create projects/{プロジェクト名}/topics/XXXX
```

### サブスクリプションの登録

```
$ gcloud alpha pubsub subscriptions create projects/{プロジェクト名}/subscriptions/YYYY --topic projects/{プロジェクト名}/topics/XXXX --topic-project ｛プロジェクト名｝
```

### トピックへメッセージを登録

```
$ gcloud alpha pubsub topics publish {トピック名} '{"message":"Hello World!"}'
1 message(s) published.
 - messageId: メッセージID
```

### サブスクリプションからメッセージをpull

```
$ gcloud alpha pubsub subscriptions pull ｛サブスクリプション名｝ 
┌────────────────────────────┬────────────────┬────────────┬───────────────────────────────────────────────────────
─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│            DATA            │   MESSAGE_ID   │ ATTRIBUTES │                                                       
                      ACK_ID                                                                             │
├────────────────────────────┼────────────────┼────────────┼───────────────────────────────────────────────────────
─────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ {"message":"Hello World!"} │ 35010637313331 │            │ M0VBXkASTDoGRElTK0MLKlgRTgQhIT4wPkVTRFAGFixdRkhRNxkIaF
EOT14jPzUgKEUSAAgUBXx9cV9UdV1YGgdRDRlyfGRwawxCUwVMBypVWxENQGx-SwRUDRhye2JyaVsQAgFEe7DsyqM8Zhs9XxJLLD5-MQ │
└────────────────────────────┴────────────────┴────────────┴───────────────────────────────────────────────────────
─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```

### ACK IDを指定してトピックからメッセージを削除する。
```
$ gcloud alpha pubsub subscriptions ack {サブスクリプション名}　｛ACK ID｝
1 message(s) acknowledged for subscription xxx

$ gcloud alpha pubsub subscriptions pull {サブスクリプション名}
Listed 0 items.
```

### サブスクリプションからPULLするときに自動でACKを返して削除する。

```
$ gcloud alpha pubsub subscriptions pull --auto-ack {サブスクリプション名} 
┌────────────────────────────┬────────────────┬────────────┐
│            DATA            │   MESSAGE_ID   │ ATTRIBUTES │
├────────────────────────────┼────────────────┼────────────┤
│ {"message":"Hello World!"} │ 35009734804951 │            │
└────────────────────────────┴────────────────┴────────────┘

$ gcloud alpha pubsub subscriptions pull --auto-ack ｛サブスクリプション名｝
Listed 0 items.
```