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

プロダクト間連携を支える非同期通信基盤

 プロダクト間連携を支える非同期通信基盤

Encraft #16 の登壇資料です。
日時: 2024/7/29 (月) 19:00 〜 21:00
URL: https://knowledgework.connpass.com/event/324204/

Shota Iwamatsu

July 29, 2024
Tweet

More Decks by Shota Iwamatsu

Other Decks in Technology

Transcript

  1. © LayerX Inc. 2 • LayerX ◦ 2023/8〜 ◦ バクラク事業部

    カード開発グループ ◦ ソフトウェアエンジニア • ex. Infcurion, Latona, Accenture • 主に Go と React を書いています。 自己紹介 Shota Iwamatsu @shota8511_tech
  2. © LayerX Inc. 4 バクラクの開発の特徴 発表内での用語の定義 • プロダクト ◦ お客様に1つのパッケージとして価値を提供するソフトウェア製品

    ◦ 「バクラクビジネスカード」など • サービス ◦ 論理的あるいは物理的に分けられた1つのサーバーアプリケーション ◦ マイクロサービス・アーキテクチャにおける「サービス」と概ね同等
  3. 6 © LayerX Inc. バクラクの開発の特徴 仕訳・支払処理効率化 法人カードの発行・管理 稟議・支払申請・経費精算 帳票保存・ストレージ 帳票発行

    * 経費精算のSlack連携は申請内容の通知のみ AIが領収書を5秒でデータ化 スマホアプリとSlack連携あり 領収書の重複申請などミス防止機能 AIが請求書を5秒でデータ化 仕訳・振込データを自動作成 稟議から会計までスムーズに連携 年会費無料で何枚でも発行可 インボイス制度・電帳法対応 すべての決済で1%以上の還元 AIが書類を5秒でデータ化 あらゆる書類の電子保管に対応 電子取引・スキャナ保存に完全対応 帳票の一括作成も個別作成も自由自在 帳票の作成・稟議・送付・保存を一本化 レイアウトや項目のカスタマイズも可能 ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・
  4. © LayerX Inc. 8 バクラクの開発の特徴 • ビジネスカード は決済後の業務 (AfterPay) をバクラクにする機能を提供している。

    ◦ 申請・経費精算 と連携して、カード明細に対して証憑を紐づける & 利用報告をする。 ◦ 請求書受取・仕訳 と連携して、カード明細に対して仕訳を作成する。 例えば・・・ これを実現するために、プロダクト間でデータを連携する必要がある。
  5. © LayerX Inc. 9 バクラクの開発の特徴 各プロダクトはそれぞれ専用のサービスを持っている。 前提となるアーキテクチャ 請求書受取・仕訳 申請・経費精算 ビジネスカード

    Service Service Service データ参照・更新 データ参照・更新 データ参照・更新 ※ 細かい構成は今回の話では重要ではないため仮のものです。
  6. © LayerX Inc. 10 バクラクの開発の特徴 プロダクト間連携を実現するために、データを1つの DB に集約する必要がある。 前提となるアーキテクチャ 請求書受取・仕訳

    申請・経費精算 ビジネスカード Service Service Service データ参照・更新 データ参照・更新 データ参照・更新 複数サービスのデータを紐づけて 検索・表示したい! ※ 細かい構成は今回の話では重要ではないため仮のものです。
  7. © LayerX Inc. 11 バクラクの開発の特徴 AfterPay 専用サービスとして切り出し、各サービスから関連データを同期する。 前提となるアーキテクチャ 請求書受取・仕訳 申請・経費精算

    ビジネスカード Service Service AfterPay Service Service データ同期 データ同期 データ同期 ※ 細かい構成は今回の話では重要ではないため仮のものです。 データ参照・更新 データ参照・更新 データ参照・更新
  8. © LayerX Inc. 12 バクラクの開発の特徴 各プロダクトから、サービス横断的なデータを参照できる。 前提となるアーキテクチャ 請求書受取・仕訳 申請・経費精算 ビジネスカード

    Service Service AfterPay Service Service データ参照 データ参照 ※ 細かい構成は今回の話では重要ではないため仮のものです。 データ参照・更新 データ参照・更新 データ参照・更新
  9. © LayerX Inc. 14 バクラクの開発の課題感 • プロダクト間連携において、サービス間の非同期通信が発生しやすい。 ◦ サービス同士を疎結合に保ちつつ、データを同期したい。 ◦

    あるサービスのデータ更新をトリガーに、別サービスで処理を実行したい。 • プロダクトやプロダクト間連携は今後もどんどん増えていく。 • その度にサービス間の非同期通信の仕組みを用意するのは大変... 課題感
  10. © LayerX Inc. 15 バクラクの開発の課題感 • プロダクト間連携において、サービス間の非同期通信が発生しやすい。 ◦ サービス同士を疎結合に保ちつつ、データを同期したい。 ◦

    あるサービスのデータ更新をトリガーに、別サービスで処理を実行したい。 • プロダクトやプロダクト間連携は今後もどんどん増えていく。 • その度にサービス間の非同期通信の仕組みを用意するのは大変... 課題感 サービス横断的な非同期通信基盤を用意し、開発の手間を削減!
  11. 17 © LayerX Inc. 非同期通信基盤のアーキテクチャ • AWS の EventBridge +

    SQS で非同期処理を実現している。 • EventBridge にイベントを送れば、対象の RPC が非同期で実行される。 全体像
  12. 18 © LayerX Inc. 非同期通信基盤のアーキテクチャ • Publisher が Event Bus

    にイベントを送る。 • Event Bus は1つのみ存在し、あらゆるイベントを受け取る。 • イベントに含まれる主なパラメータは、イベント名・ペイロードなど。
  13. 19 © LayerX Inc. 非同期通信基盤のアーキテクチャ • イベントごとに定義された Rule をもとに、対象の RPC

    を特定する。 • Rule に紐づく Input Transformer でイベントのパラメータを整形する。 ◦ メタデータとして対象の RPC 名を追加する。
  14. 20 © LayerX Inc. 非同期通信基盤のアーキテクチャ • SQS (と DLQ) が

    RPC ごとに1つ存在する。 • 対象の RPC に対応する SQS へメッセージをエンキューする。
  15. 21 © LayerX Inc. 非同期通信基盤のアーキテクチャ • Worker が全ての SQS をポーリングしている。

    • 受信したメッセージをもとに対象の RPC を特定する。 • DynamoDB で冪等性を担保しており、メッセージが処理済みの場合は何もしない。
  16. 22 © LayerX Inc. 非同期通信基盤のアーキテクチャ • Worker が対象の RPC を実行する。

    • RPC から正常応答が返ってきたら SQS のメッセージを削除する。 • RPC は Connect (gRPC 互換フレームワーク) で実装されている。
  17. © LayerX Inc. 23 非同期通信基盤のアーキテクチャ • イベントの送信先が1つなので、Publisher が送信先を意識する必要がない。 • メッセージを一度

    SQS に入れているので、リトライがしやすい。 • メッセージの受信処理は Worker に任せて、RPC のみ実装すれば良い。 嬉しいポイント
  18. 24 © LayerX Inc. 非同期通信基盤のアーキテクチャ • SQS を経由せずとも、EventBridge から直接 RPC

    サーバーへリクエストを送ることはできる。 • ただし5秒タイムアウトがあるため、バクラクでは SQS を経由している。 補足
  19. © LayerX Inc. 26 開発者がやること ③ ルール定義 ② RPC 実装

    ① イベント定義 • イベントと RPC の紐づけを定義すると、必要なリソースが自動生成される。 • 開発者は RPC の実装に集中できる。
  20. © LayerX Inc. 28 開発者がやること 1. イベント定義 • proto ファイルにイベントとそのペイロードを定義する。

    enum Event { EVENT_HOGE_UPDATED = 1; … } message HogeUpdatedEvent { string hoge_id = 1; } event.proto
  21. © LayerX Inc. 30 開発者がやること 2. RPC 実装 • 非同期で実行したい

    RPC を定義 & 実装する。 • リクエストはイベントのペイロードを受け取る。 service NotificationService { rpc NotifyHogeUpdated(NotifyHogeUpdatedRequest) returns (google.protobuf.Empty) {} } message NotifyHogeUpdatedRequest { HogeUpdatedEvent event = 1; } notification.proto
  22. © LayerX Inc. 32 開発者がやること 3. ルール定義 • yaml ファイルにイベントと

    RPC の紐づけを定義する。 • この定義から EventBridge Rule と SQS の自動生成される (by Terraform)。 event: - name: 'event_hoge_updated' # このイベントが発行されると subscriber: - id: 'NotificationService/NotifyHogeUpdated' # この RPC が実行される … event_router.yaml
  23. © LayerX Inc. 33 開発者がやること 非同期で RPC が実行される! イベントを発行すると •

    Publisher がイベントを発行すれば、対象の RPC が非同期で実行される。
  24. © LayerX Inc. 34 開発者がやること • イベントと RPC の紐づけを定義すると、必要なリソースが自動生成される。 •

    開発者は RPC の実装に集中できる。 • イベントと RPC の紐づけが一目でわかる。 嬉しいポイント