もう1ヶ月以上経過してしまいましたが、まだ情報が少ないみないなので、aws識者として競合との比較も含めて書きます。私は使わないと頭に入らない人間なので、ちょっと触ります。
概要
What is Google Cloud Pub/Sub? - Cloud Pub/Sub — Google Cloud Platform
の絵で大体想像がつくと思いますが、文字通り Pub/Subを実現するものです。
最初にPub/Subを見た時、AWS SNSをイメージしましたが、どうやら違うようです(一部重複の部分もある)。
じゃあSQSかとも思いまいたが、どうやらこれとも違うようです(使い方によっては一部重複する)。
Pub/Sub自体の機能については、結構言及されているので、
これも参考にしながら、まずはAWSとの比較から書きます。
競合比較
SNSとの違い
SNSは原則Push型です。Pub/Subは Push or Pull ですので、一部機能は重複しています。この辺りをまとめると
- SNSはPub/Subだが、Pushしか出来ない
- SNSはPush先が豊富 Mail, HTTP(s), SQS(AWS内のサービス連携), モバイルプッシュ など、かなりアプリケーションに突っ込んだところまで実装している。
- Pub/Sub が対応している Pushは HTTPSのみ(2015/04/29)
SQSとの違い
SQS自体にPub/Subの機能はありません。SQSと競合するサービスは、Google Task Queue
です。両方古くからあるサービスなので、最初 Pub/Subと聞いての競合はSNSだと思いました。
- SQSはそもそもPub/Subではない
- SNSとSQSは連携できるので、組み合わせればPub/Sub & Pull型は一応できる(管理が大変そう)
- Cloud Pub/Sub の Pullは SQSそのものだが、単純にキューを使いたいならTask Queue
で十分
総合的にみて
現状 Cloud Pub/Sub は Pull主体です。Pushは HTTPSに限定されているので、Push型のsubscriberはそんなに増やせない。よって、Pull型のSNS(Queue付きのSNS) = Cloud Pub/Sub というイメージ。互いに似て非なるものです。
Cloud Pub/Sub (subscriber視点)
こちらをご一読。
Subscriber Guide - Cloud Pub/Sub — Google Cloud Platform
- Pullならポーリング当たり前だけどリアルタイム性はさがるよ
- Pullなら通信費かさむよ
- Pushなら HTTPSのエンドポイント用意して!
- PushのエンドポイントはGAE(App Engine)ほぼ一択、DNS通さないとダメみたい
GAEか、勉強するぞ!いつか。
実践
サンプル動かす
GAEのサンプルは書かれている方がおりますので、GCEというかローカルPCで動かします。よってsubscriberはpullです。
Googleといえばpythonなので、python一択
READMEに従い、venvに必要なpipをぶち込みます。
オプション無しで叩くと、使い方が出ます。
$ python pubsub_sample.py Available arguments are: PROJ list_topics PROJ create_topic TOPIC PROJ delete_topic TOPIC PROJ list_subscriptions PROJ list_subscriptions_in_topic TOPIC PROJ create_subscription SUBSCRIPTION LINKED_TOPIC [PUSH_ENDPOINT] PROJ delete_subscription SUBSCRIPTION PROJ connect_irc TOPIC SERVER CHANNEL PROJ publish_message TOPIC MESSAGE PROJ pull_messages SUBSCRIPTION
コマンドは叩いてもらうとわかるとして、気になる実装connect_ircをみてみます。ircの特定チャネルの情報を流すらしいですが、実装は単純に
while True: readbuffer = readbuffer + irc.recv(1024) temp = readbuffer.split('\n') readbuffer = temp.pop() for line in temp: line = line.rstrip() parts = line.split() if parts[0] == "PING": irc.send("PONG {}\r\n".format(parts[1])) else: i = line.find(priv_mark) if i == -1: continue line = line[i + len(priv_mark):] m = p.match(line) if m: line = "Title: {}, Diff: {}".format(m.group(1), m.group(2)) body = { 'messages': [{'data': base64.b64encode(str(line))}] } client.projects().topics().publish( topic=topic, body=body).execute(num_retries=NUM_RETRIES)
ircのチャネルをポーリングしてpubしているだけです。サンプルとしてはひと通り動かせばよく分かり、どう実装するかも余計な部分がほとんど無いので、コードを読めばすぐわかる感じです。
まとめ
- pull主体
- pushやるならGAE
- Cloud Loggingとの連携、pushでスマートにやるならGAE一択
- 単純なキューなら、Task Queue使ったほうがいい(多分)