$30 off During Our Annual Pro Sale. View Details »

Cloud Pub/SubのSubscriberとしてCloud Functionsを使ってみた

Cloud Pub/SubのSubscriberとしてCloud Functionsを使ってみた

Avatar for at-ishikawa

at-ishikawa

June 15, 2018
Tweet

Other Decks in Programming

Transcript

  1. • サービスの概要 • Cloud Pub/Sub • Cloud Functions • Cloud

    Functionsの独特だと思ったところ • 主にServerlessとしての点 3 今回の話
  2. 1. Cloud Functionsを利用した機能 2. Pub/Subについて 3. Cloud Functionsについて 4. Cloud

    Functionsで気づいたこと a. アプリケーション b. インフラストラクチャ 5. 今後のCloud Functionsの利用 6. まとめ Agenda 4
  3. 1. Cloud Functionsを利用した機能 2. Pub/Subについて 3. Cloud Functionsについて 4. Cloud

    Functionsで気づいたこと a. アプリケーション b. インフラストラクチャ 5. 今後のCloud Functionsの利用 6. まとめ Agenda 6
  4. • Pub/Subの特性 a. Pub/SubはAt Least Onceなメッセージ配信 • つまり、Subscriberは同じメッセージを1回以上受信する • Subscriberは冪等であるべき

    b. Publishされた順番にはメッセージはSubscribeされない • 順番を考慮する必要がないようにSubscriberを開発する 9 Pub/Subについて
  5. 1. Cloud Functionsを利用した機能 2. Pub/Subについて 3. Cloud Functionsについて 4. Cloud

    Functionsで気づいたこと a. アプリケーション b. インフラストラクチャ 5. 今後のCloud Functionsの利用 6. まとめ Agenda 10
  6. • Cloud Functions (Beta版) • Serverless ApplicationのためのFaaS • Runtime •

    Node.js v6.14.0 • Cloud Functions for Firebase • Firebase側と連携して機能追加したいとき • Cloud Functionsとは多少違う • デプロイ方法 • エントリポイント • Emulator 11 Cloud Functionsについて
  7. • Cloud Functionsのイベントトリガー a. Background functions i. Pub/Subのmessage ii. Google

    Cloud Storage bucketの変更 b. Http function i. HTTPリクエスト 12 Cloud Functionsについて
  8. • Background Functionsの例 • Pub/Sub用のfunction • helloWorldがfunction名(デプロイ時に変更可能) 13 Cloud Functionsについて

    $ cat function.js exports.helloWorld = (event, callback) => { const pubsubMessage = event.data; const data = pubsubMessage.data ? Buffer.from(pubsubMessage.data, 'base64').toString() : 'No data'; console.log(`${data}`); callback(); };
  9. • Background Functionsの例 • Pub/Subからデータevent.dataを受け取りログにdataを出力 • Pub/Subの読み込み, ackなど、Pub/Subの制御に関する処理 が不要 14

    Cloud Functionsについて $ cat function.js exports.helloWorld = (event, callback) => { const pubsubMessage = event.data; const data = pubsubMessage.data ? Buffer.from(pubsubMessage.data, 'base64').toString() : 'No data'; console.log(`${data}`); callback(); };
  10. • Background Functionsの例 • functionの完了処理 i. エントリポイントの引数callbackをcall ii. Promiseをreturn 15

    Cloud Functionsについて $ cat function.js exports.helloWorld = (event, callback) => { const pubsubMessage = event.data; const data = pubsubMessage.data ? Buffer.from(pubsubMessage.data, 'base64').toString() : 'No data'; console.log(`${data}`); callback(); };
  11. • Background Functions • Pub/Subの制約を考慮するべき • メッセージの順番、冪等性 • Pub/SubのメッセージにはIDのみある •

    Subscriber側で常に最新のデータをIDから取得して、上書きする 16 Cloud Functionsについて
  12. 1. Cloud Functionsを利用した機能 2. Pub/Subについて 3. Cloud Functionsについて 4. Cloud

    Functionsで気づいたこと a. アプリケーション b. インフラストラクチャ 5. 今後のCloud Functionsの利用 6. まとめ Agenda 18
  13. • Background functionのRetry • Background functionの場合、retryというオプションがある • 有効化すると、エラーになった場合、functionを再実行 • callbackの第1引数がnot

    null • Promiseがrejectされる • エラーが出続けている場合、数日間リトライを繰り返す 20 アプリケーション
  14. • Background functionのRetry • Retryできるケースとできないケースを考える • 一時的なエラーの場合は復旧できる可能性があるのでリトラ イさせる • rejectしたPromiseを返す

    • 復旧不能なエラーの場合、リトライさせない • rejectしていないPromiseを返す • エラーをログに出力 • 数日間リトライを繰り返させない • 一定期間リトライしたら処理しない 21 アプリケーション
  15. • Background functionのRetry • Retryできるケースとできないケースを考える 22 アプリケーション Retry可能なエラー Retry不要なエラー •

    DBレプリケーション遅延に よるデータ取得エラー • 外部APIのリミット制限 • Pub/Subメッセージの Validationエラー • id重複登録エラー
  16. • 環境変数 • Credential情報はGitHubのリポジトリに管理しない i. Firebase config • Cloud Functions

    for Firebaseの場合、利用できる ii. GCSなど外部から動的取得 iii. デプロイ時にproduction用の環境変数用ファイル作成 • 今回はこっちを利用した • Credential以外はdotenvやnode-env-runなどで良い i. 今回は試せていない 23 アプリケーション
  17. • 環境変数 i. Firebase config • Cloud Functions for Firebaseの場合、利用できる

    • Configをプロジェクト内のすべてのfunctionで共有している • テスト時には何も取得できない • 変数名はLowercaseのみ 24 アプリケーション $ firebase --project mercari-us-double-dev functions:config:get { "echo_function": { "api": { "access_token": "echo token" }, "event_name": "echo event" } }
  18. • アプリケーション a. Background functionのRetry b. 環境変数 • インフラストラクチャ a.

    ロギング・モニタリング b. デプロイ 25 Cloud Functionsで気づいたこと
  19. • ログの仕様 • Stack Driverとの連携 • alertの設定もできる • ログ •

    function実行数 • OK (Health check) • Error (Error alert) • メトリクスも見れる • 実行時間 • メモリ使用量 • ネットワーク量 28 インフラストラクチャ
  20. • デプロイ方法 a. Google Cloud Source Repositoriesを利用する方法 • GitHubのリポジトリのミラーとして利用できる •

    デプロイするブランチ名やタグ名を指定できる • 更新で自動deployされる • プライベートパッケージに依存している場合は.npmrcファイル も管理 b. gcloudコマンドからデプロイする • 今回はCI上でこれを実行 • .npmrcの動的生成 • credential情報の動的生成 29 インフラストラクチャ
  21. • デプロイ方法 • プライベートパッケージの利用 • .npmrcファイルがルートディレクトリに必要 • プライベートレジストリへのアクセス • jfrog

    30 インフラストラクチャ @mercari:registry=https://mercari.jfrog.io/path/to //mercari.jfrog.io/path/to/:_password=<Base64 encoded password> //mercari.jfrog.io/path/to/:username=at-ishikawa //mercari.jfrog.io/path/to/:[email protected] //mercari.jfrog.io/path/to/:always-auth=true
  22. その他 1. ローカル開発環境 • Emulatorがある 2. 外部APIのスキーマが分かりづらい • FlowかTypeScript入れるべきだった •

    Sourcemapがどうなるかは要調査 3. イベントをトリガーしたあとの処理のみ書く • HttpフレームワークのMiddlewareのような処理を追加しづらい 4. テストが書きやすい • 普通の関数にテストデータを生成して実行するだけ 5. マルチプロジェクト対応 • 別GCPプロジェクトに存在する Pub/SubのTopicをTriggerにはできない 6. serviceaccountsはGCPのデフォルトが使われている • GCPサービスの連携が容易。認証情報を考える必要がアプリケーションないでは必要ない 7. Cloud Functions for Firebase • デプロイ方法がgcloudからfirebaseに。firebaseはOAuthしてトークン生成が必要 • エントリポイントの書き方が変わる。 topic名がコードに入ってしまうので、環境ごとに変えるためにはコードを書かないといけない • Firebaseコマンドでemulatorを使用する 8. Serverless frameworkを使わなかった理由は? • パッと見て使いたいmotivationにはならなかった。でも将来的に良い機能があると判断したら導入するかも 31 Cloud Functionsで気づいたこと
  23. • 開発環境での複数function • 目的は開発環境でのQAの容易化 • GitHubのPRと連携 • Pub/Subを可変にする • monorepoで管理

    • デプロイ容易化 • functionをすぐに開発できるように 32 今後のCloud Functionsの利用
  24. • Cloud Functionsを使ってみて • 簡単にPub/Sub Subscriberが作れる • Retryの仕組みは便利だが、エラーを意識する • インフラの仕組みも基本的に整っている

    • モニタリングの仕組みはStack Driverと連携できる • デプロイは多少考えないといけない場合がある 33 まとめ