copyright Fringe81 Co.,Ltd.
GCP本格採用で遭遇した課題と
マイクロサービス的解決
第3回 Google Cloud INSIDE
Fringe81株式会社 豊島正規
copyright Fringe81 Co.,Ltd.
About me (@mtoyoshi)
本日は8Fよりやってまいりました
Scalaエンジニア
 ・サーバーサイド
 ・Ad-Tech領域を長く
共に働く仲間と送り合う
ピアボーナスを実現するサービス
〜サイレントヒーローの発見〜
copyright Fringe81 Co.,Ltd.
2017年12月に子会社として
Unipos株式会社発足
copyright Fringe81 Co.,Ltd.
2017年12月に子会社として
Unipos株式会社発足
不思議とモノリス(大企業化)を避けて
マイクロサービス化した話に見えてきます
copyright Fringe81 Co.,Ltd.
本日のテーマ
GCP
x
マイクロサービス
x
アプリ開発の裏側
copyright Fringe81 Co.,Ltd.
Why?
copyright Fringe81 Co.,Ltd.
新規事業はエンジニアリソース少ない
当初しばらくは売上・利益がない
copyright Fringe81 Co.,Ltd.
新規事業はエンジニアリソース少ない
当初しばらくは売上・利益がない
アプリケーション開発専念
コストを抑えたい
copyright Fringe81 Co.,Ltd.
GAE(PaaS)がキラーコンテンツ
その他多くのサービスで
無料枠が設定されている
copyright Fringe81 Co.,Ltd.
スマホアプリの提供でFirebase利用
スマホアプリへの通知やリアルタイム更新など
iOS
Android
Synchronize
Data Across
Devices
Firebase
Web
copyright Fringe81 Co.,Ltd.
アプリ開発の裏側では
試行錯誤がありました
copyright Fringe81 Co.,Ltd.
> GAE(PaaS)がキラーコンテンツ
GAEの制約により自社技術が微妙にマッチしない
GAEに寄せる? 自分達流を貫く?
いいとこ取り出来る?
copyright Fringe81 Co.,Ltd.
> 多くのサービスで無料枠が設定
たとえばDBを例に取ると
cloud datastore? cloud SQL?
無料枠のありなしやその他特徴の違いを考慮
datastoreかな、、いやSQLが無難かな
copyright Fringe81 Co.,Ltd.
> スマホアプリの提供でFirebase利用
Firebaseにまつわる失敗事例を共有
当初の目的以外の効果もあったので共有
copyright Fringe81 Co.,Ltd.
さて
copyright Fringe81 Co.,Ltd.
Fringe81では Scala(JVM言語)を採用
GAEのJavaは7(※)で
Scalaの最新ver.はJava8を要求
※現在はJava8です
copyright Fringe81 Co.,Ltd.
あと、GAE/JはServletコンテナ縛りなので
使う予定だったWebフレームワーク使えない
copyright Fringe81 Co.,Ltd.
GAE flexible environment
というのがあった
(プレーンなJava8環境)
copyright Fringe81 Co.,Ltd.
copyright Fringe81 Co.,Ltd.
インスタンスの起動時間
(スケールアウト性能)
ミリ秒オーダー(S) vs 分オーダー(F)
copyright Fringe81 Co.,Ltd.
料金
インスタンス時間(S)
vs
vCPU/メモリ/永続ディスクの使用量(F)
copyright Fringe81 Co.,Ltd.
メモリ
最大1GB(S) vs 最大6GB(F)
copyright Fringe81 Co.,Ltd.
その他、flexibleはstandardの
taskqueueやmemcached無かったり
standardほどstackdriver群との
統合感はなかったりします
copyright Fringe81 Co.,Ltd.
copyright Fringe81 Co.,Ltd.
“フレキシブル環境は、
スタンダード環境を補完することを目的
としています。”
copyright Fringe81 Co.,Ltd.
なるほど・・・
いっそ、最近事例をよく聞く
GAE(S) x Goというのはどうだろう?
copyright Fringe81 Co.,Ltd.
事実、サービスの方向性を探る期間の
プロトタイプをGAE(S) x Go x datastoreで
技術検証を兼ねながら高速開発
※このときはマイクロサービス化は無し
copyright Fringe81 Co.,Ltd.
検証が終わると同時に
コードは一旦捨てて再検討
GAE(S) よかった
Goもよかった、Scalaの良さも再確認できた
copyright Fringe81 Co.,Ltd.
当初どちらかに寄せようと思っていたが
最終的にはハイブリッドでいくことに
Go
App Engine Standard
Scala
App Engine Flexible
copyright Fringe81 Co.,Ltd.
使い分けは?
Go
App Engine Standard
Scala
App Engine Flexible
copyright Fringe81 Co.,Ltd.
Go
App Engine Standard
Scala
App Engine Flexible
CQRSに基づく
Command (更新系) Query (読込系)
Responsibility Segregation(責務 分離)
copyright Fringe81 Co.,Ltd.
Go
App Engine Standard
Scala
App Engine Flexible
CQRSに基づく
Command (更新系) Query (読込系)
Responsibility Segregation(責務 分離)
※この場合のflexibleはstandardの
補完的位置づけではない
copyright Fringe81 Co.,Ltd.
It is not possible to create an optimal solution
for searching,reporting,and processing transactions
utilizing a single model.
-CQRS documents by Greg Young-
copyright Fringe81 Co.,Ltd.
Command(更新系) Query(読込系)
アクセス量に
占める割合
少 多
スケール性 △ ◎
複雑さの傾向 ビジネスロジック データ量と応答速度
(R)DB傾向 正規化 非正規化(速さ重視)
CとQの特徴
copyright Fringe81 Co.,Ltd.
Command(更新系) Query(読込系)
アクセス量に
占める割合
少 多
スケール性 △ ◎
複雑さの傾向 ビジネスロジック データ量と応答速度
(R)DB傾向 正規化 非正規化
更新系は最も得意なScalaで堅牢に作る
Cならflexibleのスケール性は弱点になりにくい
copyright Fringe81 Co.,Ltd.
Command(更新系) Query(読込系)
アクセス量に
占める割合
少 多
スケール性 △ ◎
複雑さの傾向 ビジネスロジック データ量と応答速度
(R)DB傾向 正規化 非正規化
常時稼働だが最小限でコスト対策
メモリ量のカスタマイズ性高くて安心
copyright Fringe81 Co.,Ltd.
Command (GAE flexible)
Adapters
DB
UseCases
Entities(Domains) Repository
RepositoryImpl
Controller
UseCase
Presenter
DDD x CleanArchitecture
copyright Fringe81 Co.,Ltd.
Command(更新系) Query(読込系)
アクセス量に
占める割合
少 多
スケール性 △ ◎
複雑さの傾向 ビジネスロジック データ量と応答速度
(R)DB傾向 正規化 非正規化
standard x Goの速さ・スケール性が活きる
メモリが少し不安だったがGoなら大丈夫そう
copyright Fringe81 Co.,Ltd.
Query (GAE standard)
Controller
DAO
DB
copyright Fringe81 Co.,Ltd.
なおこのCQRS的分割が
こういう切り口だとすると
Commad Query
copyright Fringe81 Co.,Ltd.
通常(狭義)のマイクロサービス分割は
直交する方向性の切り口
microservice1
microservice2
(bounded-context from DDD)
copyright Fringe81 Co.,Ltd.
直交概念なので組み合わせ可能
microservice1
microservice2
<Command> <Query>
copyright Fringe81 Co.,Ltd.
Command
App Engine Flexible
Query
App Engine Standard
Cloud
Pub/Sub
microservice1
microservice2
マイクロサービス群の連携は
ドメインイベントのPublishとSubscribeで実現
copyright Fringe81 Co.,Ltd.
Command
App Engine Flexible
Query
App Engine Standard
Cloud
Pub/Sub
microservice1
microservice2
マイクロサービス群の連携は
ドメインイベントのPublishとSubscribeで実現
DomainEvent
copyright Fringe81 Co.,Ltd.
やってみてどうだったか?
Go
App Engine Standard
Scala
App Engine Flexible
copyright Fringe81 Co.,Ltd.
QはViewに従うという割り切り
・設計時間が大幅に減る
・Queryに最適化されたDBにより、速く、コードもシン
プルに
copyright Fringe81 Co.,Ltd.
Command
App Engine Flexible
Query
App Engine Standard
Cloud
Pub/Sub
microservice1
microservice2
DomainEvent
Cloud Datastore
Qに特化したデータに作り直す
※ Eventual Consistencyに注意
copyright Fringe81 Co.,Ltd.
datastoreでは表現できないクエリが
必要になった・・・というときは
copyright Fringe81 Co.,Ltd.
Command
App Engine Flexible
Query
App Engine Standard
Cloud
Pub/Sub
microservice1
microservice2
DomainEvent
Cloud Datastore
クエリに応じた対策を講じやすい
(C側に影響を及ぼさずに)
Cloud SQL
copyright Fringe81 Co.,Ltd.
GAE(S) x Go x memcached = 速い
CとQで言語を変えるのは難しい判断ですが
結果的には武器が増えてよかったと思います
※[前提] Goやってみたいというメンバーが多かった
copyright Fringe81 Co.,Ltd.
まとめ
● GAE(S)でいけないか?をまず考える
● GAE(F)使うなら補完的に(公式)
● CQRSという切り口でCをGAE(F)でQをGAE(S)で
● PubSubでの連携は疎結合で拡張性高い
copyright Fringe81 Co.,Ltd.
iOS
Android
Firebase
Web
次にFirebase,
mBaaSとしてではなく
copyright Fringe81 Co.,Ltd.
iOS
Android
Synchronize
Data Across
Devices
Firebase
Web
Cloud
Pub/Sub
App
Engine
Cloud
Datastoreスマホ通知やリアルタイム更新用に
copyright Fringe81 Co.,Ltd.
FCMTokenに関する失敗
スマホアプリにプッシュ通知するには
FCMTokenが必要
(Firebase Cloud Message)
copyright Fringe81 Co.,Ltd.
採番されたFCMTokenを永続化して
通知のたび利用する必要あり
copyright Fringe81 Co.,Ltd.
反省
”永続化はServerSide(Scala)の先のDB”
という思い込みが抜けていなかった
Server-Side
(Scala) DBWeb
copyright Fringe81 Co.,Ltd.
iOS
Android
Synchronize
Data Across
Devices
Firebase
Web
Cloud
Pub/Sub
App
Engine
Cloud
Datastore
datastoreに書き込むべく
スマホアプリは永続化依頼
copyright Fringe81 Co.,Ltd.
iOS
Android
Synchronize
Data Across
Devices
Firebase
Web
Cloud
Pub/Sub
App
Engine
Cloud
Datastore
ドメインイベントに
FCMTokenを含めて渡す
DomainEvent
copyright Fringe81 Co.,Ltd.
iOS
Android
Synchronize
Data Across
Devices
Firebase
Web
Cloud
Pub/Sub
App
Engine
Cloud
Datastore
ただしアプリ通知が必要ない
イベントには含まない
DomainEvent
copyright Fringe81 Co.,Ltd.
Wait !
copyright Fringe81 Co.,Ltd.
ドメインイベント発行側が
その先の利用シーンを知りすぎている
FCMTokenという技術依存のデータが
なぜドメインイベントに?
疎結合・高凝集に違反
copyright Fringe81 Co.,Ltd.
iOS
Android
Firebase
Web
Firebase Cloud Messaging用データ
なので直接保存にいくことにした
copyright Fringe81 Co.,Ltd.
これをヒントにビュー用データは
ドメイン層に持ち込まずに
ビュー用DBに保存するように
iOS
Android
Firebase
Web
copyright Fringe81 Co.,Ltd.
まとめ
当初目的以外に、FBのおかげでこのデータは
ビュー?ドメイン?という議論がしやすくなった
チーム内のデータ感度(責務を意識)が上がった
copyright Fringe81 Co.,Ltd.
〜 最後に補足的に 〜
copyright Fringe81 Co.,Ltd.
flexibleはstandardほどstackdriver群
との統合感ないと言いましたが
ちょっとした開発で近づけられます
copyright Fringe81 Co.,Ltd.
stackdriver logging
ログ出力されるがログレベルが設定されない
API呼ぶよりもflexibleのDocker上で稼働している
fluentdに持っていかせるのが吉
※詳しくはチームの仲間が書いた記事参照
https://qiita.com/chidakiyo/items/1452ab1ea83279a8e485
copyright Fringe81 Co.,Ltd.
stackdriver monitoring
FlexibleのCPU等は標準でメトリクス取得可能
copyright Fringe81 Co.,Ltd.
stackdriver trace
アプリからAPI呼び出しして利用可能に
※パフォーマンス改善・プログラム見直しにつながるので
是非有効にしておきたい
copyright Fringe81 Co.,Ltd.
以上、ありがとうございました
copyright Fringe81 Co.,Ltd.
告知:3/27 自社GCP勉強会します
https://fringe81.connpass.com/event/79893

Google cloudinside3