36 ウォレットアプリ Kyash のシステム構成 Microservices 的に複数のサービスに分かれています(※簡略化しています) API Internet カード発行 入金 家計簿連携 通知 ユーザー検索 Processing CardNetwork DB ユーザー認証 管理系機能 Internet 決済 外部サービス 外部サービス Internet Internet 社内管理 バッチ処理 Kyash
49 ふたたび、ウォレットアプリ Kyash を振り返る ※簡略化しています API Internet カード発行 入金 家計簿連携 通知 ユーザー検索 Processing CardNetwork DB ユーザー認証 管理系機能 Internet 決済 外部サービス 外部サービス Internet Internet 社内管理 バッチ処理 Kyash
50 今だから見える課題1:サービス境界がユースケース寄り API Internet カード発行 入金 家計簿連携 通知 ユーザー検索 Processing CardNetwork DB ユーザー認証 管理系機能 Internet 決済 外部サービス 外部サービス Internet Internet 社内管理 バッチ処理 Kyash ※簡略化しています
52 今だから見える課題2:共有データの存在 API Internet カード発行 入金 家計簿連携 通知 ユーザー検索 CardNetwork DB Processing ユーザー認証 管理系機能 Internet 決済 外部サービス 外部サービス Internet Internet 社内管理 バッチ処理 Kyash ※簡略化しています
54 今だから見える課題3:Orchestrator(指揮者)の肥大 API Internet カード発行 入金 家計簿連携 通知 ユーザー検索 CardNetwork DB Processing ユーザー認証 管理系機能 Internet 決済 外部サービス 外部サービス Internet Internet 社内管理 バッチ処理 Kyash ※簡略化しています
70 DBどうする問題 案1:Event Sourcing Event Store ① Busに流れるすべてのEventを記録 ② 必要となる都度、過去の Eventをすべて再生し て現在の状態を取得 ① ② Message Bus Partner User Account Card Processing Clearing Funding
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
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
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 の特殊事情
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
91 先ほどの例で登録したUserの情報を取得する場合 パートナー企業 サーバー Message Bus User Service 5 Service 2 Service 4 GET api/user/xxx Response GetUser GetUserResult Service 3 API Facade
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
103 Sagaパターンの例:決済(オーソリ) Message Bus Processi ng User Account Card 5. 各サービスは、処理が完了したら、それぞれに結果を EventとしてPublishします 6. その間、Processingは各サービスの結果 Eventを待ちます※
107 Sagaパターンの例:決済(オーソリ) Message Bus Processi ng User Account Card 11. 該当するトランザクションデータの 「Trying」の状態を「Confirmed」に書き換え、確定させます。これが Commitに相当します 12. この後に「トランザクションをConfirmedにしたよ」EventをPublishします
112 Sagaパターンの例:決済(オーソリ) Message Bus Processi ng User Account Card 該当するトランザクションデータの 「Trying」の状態を「Canceled」に書き換え、確定させます。 これがRollbackに相当します。 もちろん「トランザクションがCanceledになったよ」Eventを投げます。
137 サービスのインフラ これが複数存在し、各々が PublicなEvent用のSNSをSubscribeしています Event SNS ● SQSはFIFOにしていない(At Least Once)ため、重複排除を行います ● 複数のServerProcessが同一のMessageを受信しても問題ないよう排他制御も行います ● 現在はこのためにDynamoDBを利用しています Service 1 Service 2 Service 3