Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ウォレットアプリKyashの先 〜 Kyash Directのアーキテクチャ

ウォレットアプリKyashの先 〜 Kyash Directのアーキテクチャ

builderscon tokyo 2019で登壇した際の資料です。

Kyash Directのアーキテクチャについて
- スクラッチ開発を決めた経緯
- アーキテクチャ決定までの試行錯誤
- 関連トピック
- Microservices
- DDD
- AsyncMessaging
- Choreography
- EventDriven
- EventSourcing
- SagaPattern

岩藤圭介

August 30, 2019
Tweet

More Decks by 岩藤圭介

Other Decks in Technology

Transcript

  1. 1
    Intro / Logo
    ウォレットアプリ Kyash の先
    Kyash Direct のアーキテクチャ
    株式会社 Kyash
    岩藤 圭介(keisuke iwado)
    twitter: @k315k1010

    View Slide

  2. 2
    ● DDD、CleanAcrchitecture等にお
    ける個々の設計トピックの詳細な掘
    り下げ
    ● 具体的な実装方法、コーディング
    ウォレットアプリ Kyash の先
    Kyash Direct のアーキテクチャ
    ● KyashやKyash Directに興味を
    もっていただく
    ● 実務を通じて感じたMicroservices
    アーキテクチャのハマりどころ、注意
    した方が良いことを抑えていただく
    この発表のゴール お話ししないこと

    View Slide

  3. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    3

    View Slide

  4. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    4

    View Slide

  5. 5
    ミッション:価値移動のインフラを創る
    人びとの価値観や想いが詰まったお金。
    お店や人びと、そしてさまざまな対象にお金を自由に届けられたら、世界はもっと明るく楽しくなる。
    CEO

    鷹取 真一


    View Slide

  6. 6
    2つの事業をやっています
    ウォレット事業 Kyash Direct事業
    個人ユーザー向けウォレットアプリ「Kyash」と、B向け決済プラットフォーム「 Kyash Direct」

    View Slide

  7. 7
       2015年1月 創業
      2017年4月 ウォレットアプリ「Kyash」ローンチ
      2018年6月 リアルカード、2%インセンティブプログラム提供開始
     2019年4月 決済プラットフォーム「Kyash Direct」発表
    Visaカード発行ライセンス取得
      2015年7月 シートラウンド 1.7億円調達
     2016年後半 シリーズAラウンド 11億円調達
     to be continued….
     2019年7月 シリーズBラウンド 15億円調達
    これまでの歩み
    Kyash ローンチから2年4ヶ月

    View Slide

  8. 8
       2015年1月 創業
      2017年4月 ウォレットアプリ「Kyash」ローンチ
      2018年6月 リアルカード、2%インセンティブプログラム提供開始
     2019年4月 決済プラットフォーム「Kyash Direct」発表
    Visaカード発行ライセンス取得
      2015年7月 シートラウンド 1.7億円調達
     2016年後半 シリーズAラウンド 11億円調達
     to be continued….
     2019年7月 シリーズBラウンド 15億円調達
    これまでの歩み
    Kyash ローンチの2年後に Kyash Direct を発表

    View Slide

  9. 9
       2015年1月 創業
      2017年4月 ウォレットアプリ「Kyash」ローンチ
      2018年6月 リアルカード、2%インセンティブプログラム提供開始
     2019年4月 決済プラットフォーム「Kyash Direct」発表
    Visaカード発行ライセンス取得
      2015年7月 シートラウンド 1.7億円調達
     2016年後半 シリーズAラウンド 11億円調達
     to be continued….
     2019年7月 シリーズBラウンド 15億円調達
    これまでの歩み
    ちなみに私は約1年前のこのあたりで入社

    View Slide

  10. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    10

    View Slide

  11. 11
    誰でもすぐにつくれる
    どこでもつかえる
    すぐにわかる
    ウォレットアプリ Kyash について
    ● 自分たちで言うのもなんですが良いプロダクトだと思います
    ● ご存知なかった方、ぜひ使ってみてください!

    View Slide

  12. 12
    カード(クレジット/デビット)
    コンビニ
    銀行
    ポイント/ ギフト / リワード
    チャージ
    Kyash の特徴
    ● いろいろな方法でチャージ(コンビニ・ ATM・カード(手動/自動)・ポイント)
    ● 一瞬で送金
    ● Visa加盟店でお買い物
    ● 利用状況をリアルタイムに
    ● キャッシュバックがあって お得

    View Slide

  13. 13
    プロセシング
    アプリケーション・プログラム
    カード発行ライセンス及び当局の資金決済法に
    基づいた登録・各種ガイドライン遵守
    国内外のVisaカード加盟店からの決済処理を
    司るプロセシングシステムの構築・運用
    エンドユーザーが利用する
    アプリケーションの構築・提供
    イシュイング
    当局許認可
    スタートアップ
    システムベンダー
    銀行・
    カード会社
    Kyash の事業上の特徴
    カードの発行・利用に関わるすべてのレイヤーを垂直統合しています

    View Slide

  14. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct とは
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    14

    View Slide

  15. 15
    Kyash Direct とは
    ● 企業向けのSaaS製品です
    ● オリジナルデザインの Visaカードを、多様な形態で、安価かつスピーディに発行することができます
    ● 会員管理、カード発行、残高管理、取引履歴照会、等の機能を WebAPIで提供します
    ● 法人向けカードの発行も可能です
    物理カード モバイルペイメント
    バーチャルカード

    View Slide

  16. 16
    プロセシング
    アプリケーション・プログラム
    カード発行ライセンス及び当局の資金決済法に
    基づいた登録・各種ガイドライン遵守
    国内外のVisaカード加盟店からの決済処理を
    司るプロセシングシステムの構築・運用
    エンドユーザーが利用する
    アプリケーションの構築・提供
    イシュイング
    当局許認可
    スタートアップ
    システムベンダー
    銀行・
    カード会社
    Kyash Direct の特徴 その1
    ● パートナー企業はエンドユーザー向けアプリケーションの構築に注力 できます
    ● カード会員向けに必要な機能の実装には Kyash Direct API を利用できます
    ● 既存のアプリケーションに組み込むことも容易です

    View Slide

  17. 17
    パートナー企業が管理する
    ファンディングソース
    チャージ カード発行 決済
    国内外5,390万の
    VISA加盟店
    Kyash Direct の特徴 その2
    ● 売上金、銀行預金、与信、ポイント、仮想通貨といった、 パートナー企業の管理下にあるユーザーの金融資
    産やバリューを資金源(ファンディングソース)とすることができます
    ● ユーザー資産をダイレクトに Visa決済に利用できるようになり、 流動性を高める効果が期待できます
    カード決済に関わる実務・システムを垂直統合しているからこそ実現可能

    View Slide

  18. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    18

    View Slide

  19. 19
    Kyash と Kyash Direct は似ている
    プロセシング
    アプリケーション・プログラム
    カード発行ライセンス及び当局の資金決済法に
    基づいた登録・各種ガイドライン遵守
    国内外のVisaカード加盟店からの決済処理を
    司るプロセシングシステムの構築・運用
    エンドユーザーが利用する
    アプリケーションの構築・提供
    イシュイング
    当局許認可
    8割方は同じであるかに見えると思います

    View Slide

  20. 20
    Kyash - α + β => Kyash Direct ?
    そう考えていた時期が僕たちにもありました(今年のはじめ頃)
    CTO

    椎野 孝弘

    (入社間もない頃)

    エンジニア
    チーム

    まずは現状のウォレットとの Fit&Gap を洗い出しましょう。
    既存の資産で使えるものは使うとして、追加しなきゃならな
    い機能開発がどれくらいあるか、、、
    、、、ハイ!
    ※わかりやすさのため、一部演出を加えてお伝えしております。

    View Slide

  21. 21
    Kyash と Kyash Direct で違うところ
    ※ごく大雑把に
    Kyash Kyash Direct
    顧客 エンドユーザー(to C) パートナー企業(to B)
    マルチテナント対応 不要 必要
    エンドユーザー向けアプリ 必要 パートナー企業が提供
    エンドユーザー認証 必要 パートナー企業が提供
    法人ユーザー対応 不要 必要
    ファンディングソースの拡張性 追加開発できれば良い 相当な柔軟性がないと厳しい
    経理・財務上必要な集計 自社分のみ パートナー企業ごと
    管理系機能 社内向け 社内+パートナー企業向け
    … Kyashに機能を追加して対応する場合、影響範囲がとても大きいことが予想されるもの





    View Slide

  22. 22
    これは…かなり無理ゲー厳しいかもしれない…
    ● どこをどうイジる必要があるか、洗い出すのが大変
    ○ ドキュメント類の不在/陳腐化
    ○ メンバーの入れ替わり
    ○ 安定しているがゆえに誰も触ったことがない部分も
    ● ウォレット単体で見ても設計的に無理が出てきている
    ○ 無理やり機能追加したら近い将来、収集がつかなくなりそう
    ○ 負債を積み増してる感があって精神的にキツイ
    ● 流用できた部分についても、要件の違いから乖離が発生していく可能性が高
    い(ダブルメンテは避けられない)
    ● 新規に作る部分についても既存の設計の制約を受ける
    Kyashの拡張 厳しそう Points

    View Slide

  23. 23
    ● 今までKyashで遭遇してきた課題を根本的なアーキテクチャレベルから解決でき
    るチャンス
    ● 運用を通じて、組織全体としてのドメイン知識はローンチ当初より今の方が圧倒
    的にあるのでより良い設計ができそう
    ● 既存の実装を参考にできる
    ● 既存の設計の制約を受けない
    ● 面白そうなので開発者(私)のモチベーションが圧倒的に上がる
    スクラッチ開発 Pros.
    いっそのこと、ゼロから作るとしたら …?

    View Slide

  24. 24
    ● 作らなければならないモノが圧倒的に増える
    ● アーキテクチャの刷新を試みる場合、失敗のリスクが相応にある
    ● 新しいことを試みるので、必要な時間の見積もりが困難
    ● 社内に完全に別系統のシステムを2つ抱えることになる
    スクラッチ開発 Cons.
    いっそのこと、ゼロから作るとしたら …?

    View Slide

  25. 25
    ● 作らなければならないモノが圧倒的に増える
    ● アーキテクチャの刷新を試みる場合、失敗のリスクが相応にある
    ● 新しいことを試みるので、必要な時間の見積もりが困難
    ● 社内に完全に別系統のシステムを2つ抱えることになる
    スクラッチ開発 Cons.
    スタートアップが新しいチャレンジをするとき、
    ある程度は避けて通れない
    いっそのこと、ゼロから作るとしたら …?

    View Slide

  26. 26
    いっそのこと、ゼロから作るとしたら …?

    ● 作らなければならないモノが圧倒的に増える
    ● アーキテクチャの刷新を試みる場合、失敗のリスクが相応にある
    ● 新しいことを試みるので、必要な時間の見積もりが困難
    ● 社内に完全に別系統のシステムを2つ抱えることになる
    スクラッチ開発 Cons.
    リソースが限られているスタートアップとして、
    かなり受け入れがたい

    View Slide

  27. 27

    どうしたものか…

    View Slide

  28. 28

    ❗❗

    View Slide

  29. 29
    (再掲)Kyash と Kyash Direct は似ている
    プロセシング
    アプリケーション・プログラム
    カード発行ライセンス及び当局の資金決済法に
    基づいた登録・各種ガイドライン遵守
    国内外のVisaカード加盟店からの決済処理を
    司るプロセシングシステムの構築・運用
    エンドユーザーが利用する
    アプリケーションの構築・提供
    イシュイング
    当局許認可
    8割方は同じであるかに見えると思います

    View Slide

  30. 30
    プロセシング
    アプリケーション・プログラム
    カード発行ライセンス及び当局の資金決済法に
    基づいた登録・各種ガイドライン遵守
    国内外のVisaカード加盟店からの決済処理を
    司るプロセシングシステムの構築・運用
    エンドユーザーが利用する
    アプリケーションの構築・提供
    イシュイング
    当局許認可
    スタートアップ
    システムベンダー
    銀行・
    カード会社
    こうすれば・・・?
    ウォレットアプリ Kyash as a Partner

    View Slide

  31. 31
    CTOに報告・相談
    、、、というわけで、一見遠回りのようでも、
    ゼロから開発した方が却って早いし、今後いろいろ
    な問題にも対処しやすくなるのではないか?と考
    えているのですが…
    このとき、CTOの胸にどのような想いが去来していたのか。
    Kyash Direct が軌道に乗り、ウォレットの統合を成し遂げた暁には、
    お酒を酌み交わしつつ聞いてみたいと思います。
    ・・・

    View Slide

  32. 32
    CTOに報告・相談
    なるほど。わかりました。
    では、その線で行きましょう!
    ❗❗❗

    どうでしょう。イケてる経営陣だと思いませんか。
    Kyashではエンジニアを絶賛募集しています!!

    View Slide

  33. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計の試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    33

    View Slide

  34. ウォレットアプリ Kyash を振り返ってみる
    34

    View Slide

  35. 35
    ウォレットアプリ Kyash で利用している技術

    View Slide

  36. 36
    ウォレットアプリ Kyash のシステム構成
    Microservices 的に複数のサービスに分かれています(※簡略化しています)
    API
    Internet
    カード発行
    入金 家計簿連携
    通知
    ユーザー検索
    Processing CardNetwork
    DB
    ユーザー認証
    管理系機能
    Internet
    決済
    外部サービス
    外部サービス
    Internet
    Internet 社内管理
    バッチ処理
    Kyash

    View Slide

  37. 37
    なぜ Microservices …?
    以下、個人的な推察です
    ● Monolith にするには巨大で複雑すぎる
    ● 部分的な変更が全体に影響を及ぼすのを避けたい
    ○ 例:アプリで障害が起きてもカードは使える、等
    ○ 障害発生時のインパクトが部分ごとに大きく異なる(例:決済>通知)
    ○ 部分ごとに変更の頻度が大きく異なる(例:API>決済)
    ● 部分ごとに負荷が大きく異なる
    ○ 部分的にスケールさせたい(の問題も)
    ● 外部サービスとの接続部分を切り離しておきたい
    ○ 提携先に影響が及ぶのは避けたい
    ● 機能追加のスピードは極力落としたくない
    Kyash が Microservices を選択した理由

    View Slide

  38. サービスの数に対して、エンジニアの人数がまっ
    たく足りていない…
    38
    なぜ Microservices …?
    一方で、つらみも抱えています
    ● 『コンウェイの法則』を是とするなら、 Kyash では Microservices は採用できないこと
    になります
    ● Amazonの『ピザ2枚ルール』も…

    View Slide

  39. そもそも Micerservices を選択すべき?
    39
    Kyash Direct 設計時に考えたこと その1
    ● もともと人数が足りていなかったところに Kyash Direct を開発するためにエンジニア
    チームを分割
    ● ウォレットチームのギリギリ感をヒシヒシと感じる日々…
    ● 直近の増員は。。。

    View Slide

  40. 40
    ● 巨大かつ複雑すぎる一枚岩
    ● 部分的な変更が全体に影響
    ○ 外部サービスとの接続部分(=提携先)にも影響
    ● 部分的なスケールは不可能
    ● 機能追加の難易度は。。。
    向き合うことになるであろうモノたち
    じゃあ Monolith でやるとしたら…?

    どっちにしても地獄。。。なのか?

    View Slide

  41. 41
    冷静になって Microservices v.s. Monolith 目下の課題で比較
    ● 変更がどんどん難しくなる
    ● スケールが難しい
    ● デプロイが超ハイリスク
    ● エンジニアの人数が足りていない
    ● 運用管理がつらい(実体験として)
    ● 障害調査がつらい(実体験として)
    Microservices Monolith

    View Slide

  42. 42
    冷静になって Microservices v.s. Monolith 目下の課題で比較
    ● 変更がどんどん難しくなる
    ● スケールが難しい
    ● デプロイが超ハイリスク
    ● エンジニアの人数が足りていない
    ● 運用管理がつらい(実体験として)
    ● 障害調査がつらい(実体験として)
    Microservices Monolith
    後で変えるのは相当困難
    ● 変更難 → ゼロから作る意味がない
    ● スケール →
    ● デプロイ → 祈る
    後で変えるのが比較的容易?
    ● エンジニア → 採用がんばる
    ● 運用管理 → ツール
    ● 障害調査 → 仕込み

    View Slide

  43. 43
    こちらを選択
    ● 変更がどんどん難しくなる
    ● スケールが難しい
    ● デプロイが超ハイリスク
    ● エンジニアの人数が足りていない
    ● 運用管理がつらい(実体験として)
    ● 障害調査がつらい(実体験として)
    Microservices Monolith
    後で変えるのは相当困難
    ● 変更難 → ゼロから作る意味がない
    ● スケール →
    ● デプロイ → 祈る
    後で変えるのが比較的容易?
    ● エンジニア → 採用がんばる❗
    ● 運用管理 → ツール
    ● 障害調査 → 仕込み
    つらみは身に沁みているけれど、
    それでもやはり利点の方が大きいと判断

    View Slide

  44. 44
    ● 設計・実装が難しい
    ● 必要な最低リソース(コンピュータ・人)
    は多くなる
    ● 運用管理がつらい
    ● 障害調査がつらい
    ● 各サービス単体では小さくてシンプル
    ● 変更の影響を局所化できる
    ● スケールしやすい
    ● デプロイしやすい
    ● リソース(コンピューター・人)配分を最適化し
    やすい
    Pros. Cons.
    あえて Microservices を選択するからには
    メリットは余すところなく享受し、デメリットはできるだけなくしたい❗❗

    View Slide

  45. 45
    あえて Microservices を選択するからには
    メリットは余すところなく享受し、デメリットはできるだけなくしたい❗❗
    ● 設計・実装が難しい
    ● 必要な最低リソース(コンピュータ・人)
    は多くなる
    ● 運用管理がつらい
    ● 障害調査がつらい
    ● 各サービス単体では小さくてシンプル
    ● 変更の影響を局所化できる
    ● スケールしやすい
    ● デプロイしやすい
    ● リソース(コンピューター・人)配分を最適化し
    やすい
    Pros. Cons.
    ある意味エンジニアの腕の見せどころ

    View Slide

  46. 46
    あえて Microservices を選択するからには
    メリットは余すところなく享受し、デメリットはできるだけなくしたい❗❗
    ● 設計・実装が難しい
    ● 必要な最低リソース(コンピュータ・人)
    は多くなる
    ● 運用管理がつらい
    ● 障害調査がつらい
    ● 各サービス単体では小さくてシンプル
    ● 変更の影響を局所化できる
    ● スケールしやすい
    ● デプロイしやすい
    ● リソース(コンピューター・人)配分を最適化し
    やすい
    Pros. Cons.
    Microservices のメリットを最大限引き出すためには
    各サービスの独立性を高度に保つことが必須

    View Slide

  47. いかにして Microservices の独立性を保つか?
    47
    Kyash Direct 設計時に考えたこと その2
    今こそウォレットアプリ Kyash の開発・運用を通じて感じてきたつらみ
    培ってきたノウハウを活かすとき…!

    View Slide

  48. 48
    ポイントは大きく2つ
    1. サービスをどう分けるか?
    2. サービスをどう統合するか(連携させるか)?

    View Slide

  49. 49
    ふたたび、ウォレットアプリ Kyash を振り返る
    ※簡略化しています
    API
    Internet
    カード発行
    入金 家計簿連携
    通知
    ユーザー検索
    Processing CardNetwork
    DB
    ユーザー認証
    管理系機能
    Internet
    決済
    外部サービス
    外部サービス
    Internet
    Internet 社内管理
    バッチ処理
    Kyash

    View Slide

  50. 50
    今だから見える課題1:サービス境界がユースケース寄り
    API
    Internet
    カード発行
    入金 家計簿連携
    通知
    ユーザー検索
    Processing CardNetwork
    DB
    ユーザー認証
    管理系機能
    Internet
    決済
    外部サービス
    外部サービス
    Internet
    Internet 社内管理
    バッチ処理
    Kyash
    ※簡略化しています

    View Slide

  51. 51
    今だから見える課題1:サービス境界がユースケース寄り
    ● 複数のサービス間で共有したい概念(ユーザー、カード、残高、取引履歴、等)
    が出てくる(低凝集)
    ● これらの共有したい概念は、基本的にシステム全体にとって重要なもの
    ● 重要な概念ほど、所属先が自明でなくなり、実装が方々に散らばる
    主な問題点

    View Slide

  52. 52
    今だから見える課題2:共有データの存在
    API
    Internet
    カード発行
    入金 家計簿連携
    通知
    ユーザー検索
    CardNetwork
    DB
    Processing
    ユーザー認証
    管理系機能
    Internet
    決済
    外部サービス
    外部サービス
    Internet
    Internet 社内管理
    バッチ処理
    Kyash
    ※簡略化しています

    View Slide

  53. 53
    今だから見える課題2:共有データの存在
    ● 各サービスに個別のDBユーザーが割当てられ、論理的に分けられてはいるもの
    の、物理的には1台のDBを共有しており、課題1で指摘した「共有したい概念」に
    相当する一部のデータは、DBテーブルを介して実際に共有されている
    ● これら共有データは、事実上公開インターフェースとなっている
    ● 定義されたAPIとは異なり、SQLによる自由なRead/Writeが可能であり、すべて
    を把握しなければ安全に変更ができない(密結合)
    主な問題点

    View Slide

  54. 54
    今だから見える課題3:Orchestrator(指揮者)の肥大
    API
    Internet
    カード発行
    入金 家計簿連携
    通知
    ユーザー検索
    CardNetwork
    DB
    Processing
    ユーザー認証
    管理系機能
    Internet
    決済
    外部サービス
    外部サービス
    Internet
    Internet 社内管理
    バッチ処理
    Kyash
    ※簡略化しています

    View Slide

  55. 55
    今だから見える課題3:Orchestrator(指揮者)の肥大
    ● 各サービス間の連携を同期的なRequest/Reply方式で行っている。そのため
    複数サービスをまたがる処理の起点となるサービスが、以下のことを把握して
    全体をコントロールする必要がある
    ○ 処理全体の流れ
    ○ 各処理をどのサービスが持っているか
    ○ 各処理の呼び出しに必要なパラメータ
    ○ 各処理の戻り値の扱い方
    ○ 正しい処理の呼び出し順序
    ● 本来なら各サービスに隠蔽すべき詳細情報が呼び出し元に流出しやすい(低
    凝集/密結合)
    主な問題点

    View Slide

  56. 56
    Microservicesの独立性を保つために
    直面してきた課題と先人の知恵から学んできた、今だったらこうしたい
    1. 分割単位がユースケース
    2. 共有データ
    3. Orchestration的に連携
    1. 分割単位は境界づけられたコンテキスト(DDD)
    2. DBはサービスごとに物理的に分割
    3. Choreography的に連携

    View Slide

  57. 境界づけられたコンテキスト、どう切る?
    57
    Kyash Direct 設計時に考えたこと その3

    View Slide

  58. 境界づけられたコンテキスト
    Kyash の開発・運用を通じて散々考えてきたので、意外とシュッと決まる
    ● ノウハウがないところからスタートしていたら、とても難しかったと思います
    ● だいたい1コンテキスト内に集約ルートとなる Entityが数個くらいの感覚です( VOはたくさん)
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    58
    ※簡略化しています

    View Slide

  59. サービス同士、どう連携させる?
    59
    Kyash Direct 設計時に考えたこと その4

    View Slide

  60. 60
    Message Pub/Sub で非同期的に情報を伝達します
    Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding

    View Slide

  61. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    61
    サービスは、自身の内部で何か起きたら Message Bus に所定の Message を送ります
    (ここでは Message Bus ≒ Pub/Sub 型の何かであると考えてください)



    Userで何かが起きた

    View Slide

  62. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    62
    Message Busに届いた Message は、各サービスに Publish されます

    全体に伝わる

    View Slide

  63. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    63
    各サービスは、自身が処理すべき Message が届いたら必要な処理を実行します



    Accountが反応

    View Slide

  64. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    64
    処理する必要のない Message が届いた場合は無視します



    Partnerは無視

    Accountは何かしら処理

    View Slide

  65. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    65
    処理を実行した結果、何か起きたら(大抵は何か起きる)、また所定の Message を送りま
    す。これが繰り返されます



    View Slide

  66. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    66
    原則としてサービス間で直接の通信は行いません。必ずMessage Busを経由します



    View Slide

  67. 67
    Message Pub/Sub による非同期的な連携
    ● サービス間の依存が Message および Message Bus に一元化される(サービ
    ス間の相互依存は Message のみとなる)
    ● 起こった結果(Event)のみを気にすれば良く、処理の過程を考慮する必要が
    ない
    ● 各処理は特定の Event に対する反応として記述するため、比較的小さく収ま
    る(Event Driven)
    Pros.
    サービスを圧倒的に疎結合・高凝集にしやすい

    View Slide

  68. 68
    Message Pub/Sub による非同期的な連携
    ● Message変更の影響が大きい
    ○ Messageは公開インターフェースに相当
    ○ 項目の追加程度なら問題はありません
    ○ 項目の削除や大幅な構造変更には、Version管理、あるいは別Message
    として新たに定義して対応することになると思います
    ○ できるだけコンパイラでチェックできるようにしたいところです
    ● 提供したいのは同期的な WebAPI(HTTP Request/Response)だけど、非同
    期メッセージングでどうやる?
    ○ 後述します
    ● どこかで障害が発生した場合、データの一貫性をどうやって補償する?
    ○ 後述します
    ● 複数サービスにまたがる処理がどう動いているか追跡が困難
    ○ 後述します
    Cons.

    View Slide

  69. サービスを分割するとして、DBはどうする?
    69
    Kyash Direct 設計時に考えたこと その5

    View Slide

  70. 70
    DBどうする問題
    案1:Event Sourcing
    Event Store
    ① Busに流れるすべてのEventを記録
    ② 必要となる都度、過去の Eventをすべて再生し
    て現在の状態を取得


    Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding

    View Slide

  71. 71
    DBどうする問題
    案1:Event Sourcing
    ● 記録が追記のみで作成されるため、データ競合が発生しにくい
    ○ 排他制御の問題をある程度クリア
    ● Eventを再生しさえすればどのサービスも結果的に同じ状態を入手できる
    ○ データの一貫性の問題をある程度クリア
    ● 過去のある時点の状態に戻せる
    ● 監査証跡として有効
    ● インターフェースはEventなので(SQLではないので)、永続化機構をサービス
    ごとに分けたりしなくても問題なさそう
    Pros.

    View Slide

  72. 72
    DBどうする問題
    案1:Event Sourcing
    ● 過去のEventをすべて再生するため、Eventの数が積み上がるといずれパ
    フォーマンス問題に行き当たりそう
    ● これをクリアするためには一定期間ごとにスナップショットを作成しておいて、そ
    れ以後のEventから再生する、等の対策が必要になる
    ● 現時点の状態を見るには、Eventを再生しなければならない
    ● Eventのバージョン競合は起こりうるのでその制御は必要
    Cons.

    View Slide

  73. Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    73
    DBどうする問題
    案2:各サービスごとにDBを持つ(State Sourcing)
    DB
    DB DB
    DB
    DB
    DB
    DB

    View Slide

  74. 74
    DBどうする問題
    案2:各サービスごとにDBを持つ(State Sourcing)
    ● サービスの独立性を高く保つことができる
    ● 扱いやすい(慣れの問題?)
    ● 現時点の状態(最新のデータ)を簡単に見ることができる
    Pros.

    View Slide

  75. 75
    DBどうする問題
    案2:各サービスごとにDBを持つ(State Sourcing)
    ● データの上書きが発生するため、普通に排他制御が必要
    ● 複数サービスにまたがる処理=複数DBにまたがる処理 となるため、データの
    一貫性を担保するために補償トランザクションの仕組みが必要
    ● サービスの数だけDBが必要()
    Cons.

    View Slide

  76. 76
    DBどうする問題
    結論:各サービスごとにDBを持つ+Event Store
    Event Store
    ① 各サービスのDBでRead/Write
    ② Busに流れるすべてのEventを記録
    ③ いざというときピンポイントで 復旧に必要な過
    去のEventを再生


    Message Bus
    Partner
    User
    Account
    Card
    Processing
    Clearing
    Funding
    DB
    DB DB
    DB
    DB
    DB
    DB

    View Slide

  77. 77
    DBどうする問題
    ● Writeについてはスナップショットを毎回作成しているのと同じ
    ● ReadについてはEventの再生ではなく、常に最新の状態が保持されているDB
    から取得
    ● 必要に応じて、Event StoreからEventを取得・再生
    特徴
    結論:各サービスごとにDB+Event Store

    View Slide

  78. 78
    DBどうする問題
    ● サービスの独立性を高く保つことができる
    ● 扱いやすい(慣れている)
    ● 現時点の状態を簡単に見ることができる
    ● 過去のある時点の状態に戻すことができる
    ● 監査証跡も
    ● 障害発生時のリカバリ
    Pros.
    結論:各サービスごとにDBを持つ+Event Store

    View Slide

  79. 79
    DBどうする問題
    ● 各サービスごとのDBに対しては排他制御が必要
    ○ 排他制御を行います
    ● 補償トランザクションの仕組みが必要
    ○ 後述します
    ● サービスの数だけのDBに加えEvent Store用のストレージが必要()
    ○ べらぼうな金額ではないはず…!
    ● 通常ReadはDBから行うが、Eventの再生もありうることを前提とした設計・実
    装が必要
    ○ Event Sourcing寄りの設計・実装を行います
    ○ 具体的にはAggregateの変更はEvent生成→Event適用の手順を踏むよ
    うに統一します
    結論:各サービスごとにDBを持つ+Event Store
    Cons.

    View Slide

  80. ● WebAPIをどうやって提供する?
    ● データの一貫性をどうやって担保する?(補償トランザクション)
    ● トレーサビリティをどうやって確保する?
    80
    ここまでのおさらい
    ● Microservices でいく
    ● Microservices の利点を最大限引き出すために
    ○ サービスは境界づけられたコンテキストで切る
    ○ サービス同士の連携はMessage Pub/Subを利用したEvent Drivenな
    Choreography方式
    ○ 永続化は各サービスごとのDB+Event Store
    決まったこと ✅
    未解決の問題

    View Slide

  81. WebAPIをどうやって提供する?
    81
    Kyash Direct 設計時に考えたこと その6

    View Slide

  82. 82
    ここで、さきほどからチラホラと出てきている
    Message と Event について
    ● Message:送受信を目的として所定のフォーマットで記述されたデータ
    ● Event:過去のいずれかの時点で発生した事実(結果)がデータとして記載され
    た Messageの1種
    Message
    Event

    View Slide

  83. 83
    Event: 過去に発生した事実(結果)
    ● 一方、WebAPIの関心時は今からやってほしいこと&その結果
    ● WebAPIが実行された結果としてEventが生まれることはあっても、Eventだけ
    でWebAPIを記述することはできない
    ● Eventだけ定義されていても永久に何も起こらない
    Message
    Event
    なにかしら必要

    View Slide

  84. 84
    WebAPI に対応する Message
    ● Command
    ○ 今からやってほしいこと( Requestに対応)
    ○ 実行するサービス側でインターフェースとして定義
    ○ 実行するサービスのみが受け取る Messageの1種
    ● Document
    ○ Commandの結果(Responseに対応)
    ○ Commandを定義するサービス側でインターフェースとして定義
    ○ Command送信時に指定された返信先のみが受け取る Messageの1種
    Message
    Event
    Command
    Document

    View Slide

  85. 85
    WebAPI に対応する Message の例
    Command:RegisterUser
    ● Name:Tokichiro Kinoshita
    ● Gender:Male
    ● DateOfBirth:YYYY-MM-DD
    ● ReplyTo:api
    ● Command名
    ● Commandパラメータ
    ● Documentの返信先
    ● Event名
    ● 起こった事実の内容
    ● Document名
    ● Commandの実行結果
    ※Commandパラメータに含まれる情報は持たなくて良い
    Event:UserRegistered
    ● ID:blii3osllhcp2qsl0ao0
    ● Name:”Tokichiro Kinoshita”
    ● Gender:Male
    ● DateOfBirth:YYYY-MM-DD
    ● CreatedAt: YYYY-MM-DD
    Document:RegisterUserResult
    ● ID:blii3osllhcp2qsl0ao0
    ● CreatedAt: YYYY-MM-DD

    View Slide

  86. 86
    API Facade の導入
    これでHTTPの世界とMessagingの世界を繋ぎます
    パートナー企業
    サーバー
    Message Bus
    Service
    1
    Service
    5
    Service
    2
    Service
    4
    HTTP Req.
    HTTP Res.
    Command
    Document
    Service
    3
    ● API Facade が、WebAPI を公開します
    ● HTTP Request を、API に対応する Command に変換し、Message Bus に送ります
    ● Message Bus から Document が返されたら、HTTP Response に変換し、クライアントに返します
    API Facade

    View Slide

  87. 87
    パートナー企業
    サーバー
    Message Bus
    Service
    1
    Service
    5
    Service
    2
    Service
    4
    HTTP Req.
    HTTP Res.
    Service
    3
    ● API Facade は、Requestを受けたセッション内で同期的に 応答を返す必要があります
    ● Commandの送信後、Documentを受信するか、タイムアウトするまで 待機(Block)します
    ● API Facade が複数ノードで構成される場合、 Commandを送信したプロセスと、 Document を受け
    取るプロセスを一致させるための仕組み が必要になります
    API Facade

    Service 1
    Command
    Service 1
    Document
    API Facade の特殊事情

    View Slide

  88. 88
    Event と Command / Document の違い
    パートナー企業
    サーバー
    Message Bus
    Service
    1
    Service
    5
    Service
    2
    Service
    4
    HTTP Req.
    HTTP Res.
    Service 1
    Command
    Service 1
    Document
    Service
    3
    ● Event は、すべてのサービスに対して Publish されます
    ● Command は、Command を提供するサービスに対して Send されます
    ● Document は、Command で指定された返信先( ReplyTo)に対して Send されます
    API Facade

    View Slide

  89. 89
    先に挙げた RegisterUser の例で見てみます
    パートナー企業
    サーバー
    Message Bus
    User
    Service
    5
    Service
    2
    Service
    4
    POST api/user
    Response
    RegisterUser
    RegisterUserResult
    Service
    3
    ● Command:RegisterUser → Userサービスに Send
    ● Event:UserRegistered → 全サービスに Publish
    ● Document:RegisterUserResult → API Facade に Send
    API Facade

    UserRegistered

    View Slide

  90. Query(HTTP GET)はどうなる?
    90
    ところで…

    View Slide

  91. 91
    先ほどの例で登録したUserの情報を取得する場合
    パートナー企業
    サーバー
    Message Bus
    User
    Service
    5
    Service
    2
    Service
    4
    GET
    api/user/xxx
    Response
    GetUser
    GetUserResult
    Service
    3
    API Facade

    、、、こうなる・・・?
    不可能ではなさそうだけど、つらそう

    View Slide

  92. 92
    境界づけられたコンテキストに対応する各サービスが
    Queryに応答する責務を担う場合
    ● 複数のサービスにまたがるクエリに答えるのが難しい
    ○ 例:法人ユーザー配下の全ユーザーの今月のカード利用明細
    ● API Facade への知識の流出が起こる(例のOrchestrator肥大化)
    ○ 各サービスにクエリし、結果を合成する必要がある
    ○ どのサービスがどの情報を持っているか、どのキーで結合するか、等の情
    報を API Facade が知っておく必要がある
    ● クエリの要件が増えるたびに、関連する各サービスのメンテが発生
    ○ 常にクエリの要件を考慮した設計・実装が必要
    ● パフォーマンス的にしんどい
    Cons.
    Pros.

    View Slide

  93. もはや CQRS 一択
    (Command Query Responsibility Segregation)
    93
    Queryへの対応

    View Slide

  94. 94
    QueryMaterializer / QueryProcessor の導入
    パートナー企業
    サーバー
    Message Bus
    Service
    1
    Query
    Material
    izer
    Service
    2
    Service
    4
    HTTP GET
    Response
    Service
    3
    ● QueryMaterializer は、他のサービスと同様に Eventを受け取り、必要に応じて QueryDB を更新
    します
    ● API Facade は参照系のAPI呼び出しに対して、QueryProcessor の該当処理を呼び出します
    ● QueryProcessor は、QueryDB を参照し、必要な情報を取得して呼び出し元に返します
    API Facade

    Query DB
    Query
    Process
    or
    REST / RPC

    View Slide

  95. 95
    ● 各サービスは、何らかの変化に対して Event さえ律儀に発行していれば良く、
    Queryを意識する必要がない
    ● Queryの要件に特化したデータ構造を採用できる
    ● Queryの応答性能的に有利
    ● Queryの要件変更に対して QueryMaterializer/QueryProcessor だけで対応
    できる
    ● QueryProcessor については、Messageの世界に囚われることなくQueryに特化
    したプロトコルやフレームワークを採用できる
    ● Queryだけスケールできる
    Pros.
    CQRSの採用

    View Slide

  96. 96
    CQRSの採用
    Cons.
    ● 最新のデータが反映されるまでタイムラグがある
    ○ 数秒あるいはそれ以上の遅延が発生したとしても実用上は問題ない
    ● Eventを取りこぼすとQueryの結果にデータ更新が反映されない
    ○ Event Store からリカバリ
    ● サービスが増える/プロダクト全体として複雑性が増す
    ○ やむを得ない…

    View Slide

  97. データの一貫性をどうやって担保する?
    (補償トランザクション)
    97
    Kyash Direct 設計時に考えたこと その7

    View Slide

  98. Sagaパターンを適用します
    98
    補償トランザクション

    View Slide

  99. 99
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    1. Processingサービスから「オーソリ要求を受けたよ」 EventがPublishされます


    View Slide

  100. 100
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    2. 各サービスはMessageBusを経由して「オーソリ要求受けたよ」 Eventを受信します

    View Slide

  101. 101
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    3. 「オーソリ要求受けたよ」 Eventに対して、何かしらの責務を負っているサービスは、これに反応してそ
    れぞれに処理を行います。ここでは User、Card、Account とします




    View Slide

  102. 102
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    4. このとき、各サービスで生成されるトランザクションデータは、 「Trying」状態となります




    Trying
    Trying
    Trying

    View Slide

  103. 103
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    5. 各サービスは、処理が完了したら、それぞれに結果を EventとしてPublishします
    6. その間、Processingは各サービスの結果 Eventを待ちます※




    ※つまりProcessingは、自身が結論を下すためにどのサービスのどの Eventが必要かを知ってい
    なければなりません

    View Slide

  104. 104
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    7. Processingは、必要な結果Eventが出揃ったら最終的な判断を行い、




    View Slide

  105. 105
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    8. 一連のEventの結論として、「オーソリ承認したよ」 EventをPublishし、
    9. 同時にクライアントにも 「オーソリOKっす」的なレスポンスを返します




    View Slide

  106. 106
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    10. 各サービスはMessageBusを経由して「オーソリ承認したよ」 Eventを受信し、

    View Slide

  107. 107
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    11. 該当するトランザクションデータの 「Trying」の状態を「Confirmed」に書き換え、確定させます。これが
    Commitに相当します
    12. この後に「トランザクションをConfirmedにしたよ」EventをPublishします




    Confirmed
    Confirmed
    Confirmed



    View Slide

  108. 108
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    いずれかのサービスで結果が NGとなったり、エラー等により処理が Failした場合は、その旨を Eventとして
    Publishします




    NG/Failの場合

    View Slide

  109. 109
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    Processingは、どれか1つでもNG/Failureと返ってきたら最終的な判断を NGとします




    NG/Failの場合

    View Slide

  110. 110
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    つまり一連のEventの結論として、「オーソリ拒否したよ」 EventをPublishし、同時にクライアントに 「オーソリ
    無理っす」的なレスポンスを返します


    NG/Failの場合

    View Slide

  111. 111
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    各サービスは、MessageBusを経由して「オーソリ拒否したよ」 Eventを受信し、

    NG/Failの場合

    View Slide

  112. 112
    Sagaパターンの例:決済(オーソリ)
    Message Bus
    Processi
    ng
    User
    Account
    Card
    該当するトランザクションデータの 「Trying」の状態を「Canceled」に書き換え、確定させます。
    これがRollbackに相当します。
    もちろん「トランザクションがCanceledになったよ」Eventを投げます。




    Canceled
    Canceled
    Canceled
    NG/Failの場合
    こういう一連の流れをSagaと呼ぶらしい



    View Slide

  113. 113
    Sagaパターンのポイント
    ● 補償トランザクションをEvent Drivenに実装できる
    ● 各サービスで作成されるトランザクションデータは、Commit/Rollbackに対応する
    ためにStateを持つ必要がある
    ● Sagaに関わるEventについてはそれぞれ以下3パターンが必要
    ○ Success
    ■ OK
    ■ NG
    ○ Failure
    ● Saga単位で一意となるID(SagaID、相関ID)を付与しておくと、いたずらに他
    サービスのIDを持つ必要がなくなる上に、Saga単位のCommit/Rollbackの処理
    をある程度共通化できる可能性がある

    View Slide

  114. ● Sagaに関わるEventについてはそれぞれ以下3パターンが必

    ○ Success
    ■ OK
    ■ NG
    ○ Failure(Error)
    114
    ここで、気になった方はいらっしゃるでしょうか
    Eventって状態の変化を表すものなんじゃないの?
    (NGとかFailureでは状態は変わらないのでは?)

    View Slide

  115. 1. Cardサービスにそれ用のCommandを用意する
    2. サービスAが「このカードのチェックたのんだ」的なEventを投げ、Cardサービスがそ
    れを拾い、チェック結果をEventとして返す
    3. サービスAがCardサービスから発行されるカードの状態変化Eventをすべて拾い、
    サービスAのDBに記録してカードの状態をトレースする
    4. Queryに問い合わせて結果を取得する
    115
    これ悩みました
    例1:あるサービスAの処理の中で、あるカードが現在利用可能か否かを確認したい
    これを実現するにはどうするのが良いでしょう?
    みなさんなら、どれを選びますか?

    View Slide

  116. 3. サービスAがCardサービスから発行されるカードの状態変化Eventをすべて拾い、
    サービスAのDBに記録してカードの状態をトレースする
    4. Queryに問い合わせて結果を取得する
    116
    まず、
    この2つが以下の理由で最初に消えました。
    ● カードが現在利用可能か否かのチェックは、単なるQueryではなく、Cardドメインのビ
    ジネスロジック
    ○ Cardサービス内で行われるチェックの内容は、単なるQueryとは異なる可能性
    がある。いずれにしても依頼者は関知すべきではない
    ○ チェックを他のサービスで行うことは、ドメインのビジネスロジックが流出してい
    ることを意味する(低凝集/密結合)
    ● カードの現在の状態を正確に知っているのはCardサービスだけ(タイムラグが存在
    する)

    View Slide

  117. 117
    このとき引っかかっていたこと
    1. Cardサービスにそれ用のCommandを用意する
    2. サービスAが「このカードのチェックたのんだ」的なEventを投げ、Cardサービスがそ
    れを拾い、チェック結果をEventとして返す
    残る二者択一で、かなり迷いました
    ● Eventって状態の変化を表すものなんじゃないの?
    ● OK/NGを返すだけならEventじゃないのでは?
    ● そもそもどの集約ルートのEventになるの?

    View Slide

  118. 118
    考えるヒント
    Eventを「状態の変化を表すもの」と限定すると、
    SagaパターンではCommandとEventが入り乱れるな…?

    View Slide

  119. 119
    SagaパターンでCommandとEventが入り乱れる
    Message Bus
    Processi
    ng
    Account
    Card

    User
    あれ、なんかEvent Drivenっぽくないぞ・・・
    Orchestrationっぽくなってきたぞ・・・


    ② ②
    ③ ❓

    View Slide

  120. 120
    思い込みに気づく
    Event Sourcing の Event と
    Event Driven の Event は違う
    ● Event Sourcing
    ○ 起きた出来事(変更)をすべて記録する
    ○ 現在の状態は過去の出来事をすべて再生することで得られる
    ● Event Driven
    ○ 起きた出来事をトリガーとして処理を起動する
    ■ Pub/Sub(Producer/Consumer)型
    ■ Stream型
    ごちゃ混ぜに考えていました
    だって同じ言葉だったので…

    View Slide

  121. 121
    Event と一口に言っても種類がある
    ● Command:今からやってほしいこと
    ● Document:Commandの結果
    ● Event:起きた出来事
    ○ SourceEvent:起きた出来事+それによる変化の内容
    Message
    Event
    Command
    Document
    Source
    Event

    View Slide

  122. 122
    私たちの選択
    これを選択しました
    もうおわかりかもしれませんが
    2. サービスAが「このカードのチェックたのんだ」的なEventを投げ、Cardサービスがそれ
    を拾い、チェック結果をEventとして返す
    ● 現在は、原則としてCommand/DocumentのパターンはAPI Facadeからのみ利用
    可としています(≒ 原則 WebAPIと1:1 => Applicationの関心事)
    ● Commandを他のCommandやEventと組合わせて使用すると、あっという間に
    Orchastrator化するため、注意が必要と感じています(Commandは単体で
    Applicationの要求を満たすよう設計すべき)
    例1:あるサービスの処理の中で、あるカードが現在利用可能か否かを確認したい
    このケースでは

    View Slide

  123. 1. Userサービスにそれ用のCommandを用意する
    2. サービスAが「このユーザーIDの存在確認たのんだ」的なEventを投げ、Userサービ
    スがそれを拾って結果をEventとして返す
    3. サービスAがUserサービスから発行されるUser生成Eventを拾い、サービスAのDB
    に記録してユーザーIDの有無をトレースする
    4. Queryに問い合わせて結果を取得する
    123
    ではこういう場合は?
    例2:あるサービスAの処理の中で、あるユーザーIDが存在するか確認したい
    これを実現するにはどうするのが良いでしょう?
    みなさんなら、どれを選びますか?

    View Slide

  124. 124
    私たちの選択
    を選択しました。理由は以下です。
    3. サービスAがUserサービスから発行されるUser生成Eventを拾い、サービスAのDBに
    記録してユーザーIDの有無をトレースする
    この場合は
    ● 単なるIDの存在確認は、Userドメインのビジネスロジックとは言えない
    ○ 他のサービスでやってもビジネスロジックの流出は起きない
    ● ユーザーIDの存在確認のために都度Eventのやりとりでやるとすると、そういうニー
    ズが生まれるたびにUserサービスに各Eventに対応するための修正を入れなけれ
    ばならず、煩雑すぎる

    View Slide

  125. 125
    ● ドメイン固有のビジネスロジックと見るべきか
    ● アプリケーションの関心事と見るべきか
    ● どっちの方が(中長期的に)楽そうか
    例1:あるサービスの処理の中で、あるカードが現在利用可能か否かを確認したい
    例2:あるサービスの処理の中で、あるユーザーIDが存在するか確認したい
    この2つのケースの違いは微妙なもので、どれが絶対的に正しいというのはない気がし
    ています。私たちの場合、
    といったことを基準に、その都度議論して判断しています。
    難しいですが、だからこそ議論する価値のある内容だと思います。

    View Slide

  126. トレーサビリティをどうやって確保する?
    126
    Kyash Direct 設計時に考えたこと その8

    View Slide

  127. 分散トレーシングを仕込みます
    127
    Microservices のトレーサビリティ

    View Slide

  128. 128
    Datadogを選択した理由
    ● 分散トレーシングの結果をAPM(Application Process Monitoring)でグラフィカルに
    確認できる
    ● APMとLogを関連付けて一緒に見ることができる
    ● AWS用のプラグインが充実
    ● 分散トレーシング基盤を自前で用意する余裕はない
    ● 価格面の妥当間(Datadogも安くはないけど他のはもっと高かった)
    ● ウォレットでも使っていてとくに不満がない

    View Slide

  129. 129
    Datadogで分散トレーシングするための仕込み
    ● サービステンプレート(後述)に含まれるライブラリに仕込んでいます
    ○ Datadogのライブラリを組み込み
    ○ フレームワーク的な部分でtracerを起動
    ○ TraceID、SpanIDを引き回す
    ○ ログにTraceID、SpanIDを出力
    ● サービステンプレートを利用していればある程度勝手にトレースされます
    ○ サービスをまたぐ場合は勝手にSpanが切られる
    ○ Spanを切りたいところでStartSpan(...)すれば良い

    View Slide

  130. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計での試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    130

    View Slide

  131. 131
    ※現時点でのもので、変わる可能性があります

    View Slide

  132. 132
    132
    Kyash Directで利用している技術(※今のところ)

    View Slide

  133. 133
    Kyash と同様にGoを選択した理由
    ● 現メンバーが使い慣れている(学習コスト:低)
    ● 大きな不満がない
    ○ 書きやすさと、実行時のリソース効率・性能のバランスが良い
    ○ 強い静的型付け(ないと生きていけない)
    ● Kyashの既存実装をコードレベルで参考にできる
    ● コミュニティが活発
    ● 言語人口が多そう(採用活動❗)
    といったところです

    View Slide

  134. 134
    サービステンプレート - 構造
    ● internal
    ○ adaptor
    ■ MessageHandler(InputPort実装)
    ■ MessagePresenter(OutputPort実装)
    ■ DBアクセス周りの実装
    ○ usecase
    ■ Usecase各種
    ○ domain
    ■ Model(Entity、VO)
    ■ Factory(Model、Event)
    ■ Repository
    ■ Service
    Clean Architecture にもとづくレイヤー化と依存性の管理をしています
    DIにはWireを利用しています
    最初はいろいろと迷いましたが、今は各サービスでコードの構造が揃い、見通しが良く
    なって、修正やレビューがはかどると実感しています
    ● pkg
    ○ usecase
    ■ Command
    ■ Document
    ○ domain
    ■ Event
    ■ VO
    ● cmd
    ○ main

    View Slide

  135. 135
    サービステンプレート - ライブラリ
    ● log
    ○ 基本的にlogrusのwrapper
    ○ DatadogAPMのためのプラグイン等
    ● errors
    ○ twirpのエラーを参考にエラーの分類を規定
    ○ stack情報を持たせやすく
    ● persistence
    ○ DB接続とトランザクション管理
    ● messaging
    ○ Message Pub/Subまわりのインターフェース
    ○ 各種Message(Event、Command、Document)のインターフェース
    ○ AWS SQS/SNS用の実装
    ○ Messageの重複排除、排他制御、リトライなど
    ○ DatadogAPMのための仕込み
    以下のライブラリを自作して、基本的にすべてのサービスで利用しています

    View Slide

  136. 136
    サービスのインフラ構成
    SQS
    Server
    Process
    Server
    Process
    Server
    Process
    Agent
    Aurora
    SNS
    1サービスの基本的な構成です

    View Slide

  137. 137
    サービスのインフラ
    これが複数存在し、各々が PublicなEvent用のSNSをSubscribeしています
    Event SNS
    ● SQSはFIFOにしていない(At Least Once)ため、重複排除を行います
    ● 複数のServerProcessが同一のMessageを受信しても問題ないよう排他制御も行います
    ● 現在はこのためにDynamoDBを利用しています
    Service 1
    Service 2
    Service 3

    View Slide

  138. 138
    全体像
    Command系とQuery系に別れています
    API Facade

    Event SNS
    Query
    ● Commandは、対象サービス専用の SNS Topicに送られ、そのサービスでのみ Subscribeされます
    ○ API FacadeはEventには関与しません
    ● Queryは、MaterializeのためにEventをSubscribeするためにSQSだけ持っています
    ● API FacadeとQueryのやりとりは、MessagingではなくRPC(PBベース)となっています
    Query
    Command

    View Slide

  139. 139
    大量のAWSリソースを複雑に組み合わせて使っているので、
    ふつうにconfigとかでやっていたら なので、
    Event SNS
    Query
    ● 明確なリソース命名規約
    ○ 環境とサービスが決まればすべてのリソース名が推移的に決定
    ○ 規約に基づくオーケストレーションとAppからのリソースアクセス
    ● 個人的に「SREチーム神」と思ったポイントです
    Query
    Command
    API Facade

    View Slide

  140. 140
    ここから先、実際のコードが気になるアナタ!
    とりあえず、Kyash に来てください❗

    View Slide

  141. 目次
    01. 株式会社 Kyash について
    02. ウォレットアプリ Kyash について
    03. Kyash Direct について
    04. Kyash Direct のスクラッチ開発を決意するまで
    05. 設計での試行錯誤
    06. どう実現しているか
    07. まとめ
    08. 質疑応答(?)
    141

    View Slide

  142. 142
    まとめ(という名の感想)
    ● Microservices のメリットを本気で引き出そうとすると、考えなければならない
    ことが本当に多いです
    ● 設計に関する書籍は「読む↔実践する」を何往復かすると得るところが大きい
    です(消化に時間がかかる・反芻が必要)
    ● Event DrivenとEvent Sourcingは両立できるけれども、設計を考える際は文
    脈が異なることを意識した方がはかどります
    ● Request/Reply型の同期処理に慣れきった状態から非同期メッセージング
    によるEvent Drivenなアプリケーションを書くのは、最初はかなり難しいです
    (脳の切り替えが必要)
    ● Eventチェーンがバシッと決まるとピタゴラスイッチ的なカタルシスを感じること
    ができます
    ● 通常レベルの流量なら(IoTとかでなければ)、AWSのSQS+SNS+αは、非同
    期メッセージングによるEvent Drivenなアーキテクチャの基盤として十分実用
    的なパフォーマンスを発揮できそうです
    ● 運用はこれからなので、まだまだ試行錯誤は続きそう。。。

    View Slide

  143. 143
    最後に大事なことなのでもう一度
    Kyashではエンジニアを積極採用中です❗❗
    meetup等もやっています。気軽に遊びに来てください!

    View Slide

  144. ありがとうございました!

    View Slide

  145. Special Thanks !!
    ● builderscon tokyo 2019
    ● All Kyash Members & Users
    ○ especially: Kyash Direct Engineers
    ● @mtoyoshi

    View Slide

  146. ご意見、ご質問、ご感想など、下記 twitterアカウントにお寄せいただけたらうれしいです
    146
    twitter: @k315k1010
    Kyashでの投げ銭を体験してみたい方はコチラへ …
    Kyash ID: iwado

    View Slide

  147. View Slide