Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
モダンでフルサイクルな金融プロダクト開発 / Modern full-cycle financ...
Search
ogugu
April 16, 2023
Technology
26k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モダンでフルサイクルな金融プロダクト開発 / Modern full-cycle financial product development
ogugu
April 16, 2023
More Decks by ogugu
See All by ogugu
法人支出管理領域におけるソフトウェアアーキテクチャに基づいたテスト戦略の実践
ogugu9
1
310
事業と組織から目を逸らずに技術でリードする
ogugu9
19
9.2k
深いドメインと統合型経営プラットフォームを支えるモジュラモノリスの事例 / Modular Monolith That Support Deep Domains And Integrated Management Platform
ogugu9
31
27k
Other Decks in Technology
See All in Technology
QAと開発の両側から進める AI活用 -QAプロセスAI支援ツールキットと Inner Loop / Outer Loopの取り組み-
legalontechnologies
PRO
2
310
CloudWatchから始めるAWS監視
butadora
0
270
論語・武士道・産業革命から見る かわるもの、かわらないもの
ichimichi
8
1.4k
Claude Mythos、Fable...フロンティアAIの最新動向と企業のセキュリティ対策
flatt_security
0
160
AI時代の開発生産性を捉え直す — 経営と現場をつなぐ「開発組織のオブザーバビリティ」— / AI Dev Ex Conference 2026
tkyowa
1
1.8k
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
110k
人とエージェントが高め合う協業設計
kintotechdev
0
1k
インシデント事例と パッケージの全量解析に学ぶ ソフトウェアサプライチェーンの守り方 / supply-chain-attack-defense
flatt_security
0
1.2k
AIエージェントの知識表現と推論に なぜグラフが使われるのか - 記号的AIの復権とニューラルAIとの統合
yohei1126
1
170
reFACToring
moznion
1
790
データ活用研修 データマネジメント【MIXI 26新卒技術研修】
mixi_engineers
PRO
4
700
実践が先生だった— 新卒サーバーエンジニア1年目のリアル
mixi_engineers
PRO
0
180
Featured
See All Featured
It's Worth the Effort
3n
188
29k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Product Roadmaps are Hard
iamctodd
55
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
BBQ
matthewcrist
89
10k
Code Reviewing Like a Champion
maltzj
528
40k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
190
A designer walks into a library…
pauljervisheath
211
24k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
420
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
For a Future-Friendly Web
brad_frost
183
10k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
330
Transcript
freee finance lab の歩み 〜モダンでフルサイクルな⾦融プロダクト開発〜 ogugu (Riku Ogura) 2023年4⽉16⽇
ここに円に切り抜いた画像を入れてく ださい ogugu (Riku Ogura) • ヤフーに新卒⼊社。ヤフーショッピングのリアー キテクチャに従事。 • →
freeeへジョイン。freee⼈事労務の開発を担 当。モジュラモノリス化などに貢献。 • → SREへ社内留学。 • → ⾦融開発へ異動。freeeカードUnlimitedや新規 プロダクトの開発に従事。 • → 現在は同チームのEMを担当。 ⾦融開発 エンジニアリングマネージャー
アジェンダ • freee finance labについて • カード事業の取り組み ◦ 可⽤性を重視したマイクロサービスの初期導⼊
◦ ⼤きなスクラムから⼩さなスクラムへ ◦ DevOpsの実践による開発速度の向上 ◦ Enabling SREによって⾃律的な開発組織へ • 決済事業の取り組み ◦ マイクロサービスは成功だったか? ◦ モジュラモノリスで⼩さく始めるドメイン分割 ◦ 突き詰めながらも、挑戦や遊び⼼を • さいごに
freee finance lab について
freee finance labについて 事業をもっとラクに、もっと⾃由に、 スモールビジネスを主役にする⾦融インフラ freeeが⽬指す統合型経営プラットフォーム(ERP)と繋がる⾦融‧決済サービスによって、1つ1つの取引や事業 活動が⾃動化‧可視化され、ラクになることを⽬指します。 また、データ活⽤による与信など各種サービスの提供を受けることで、より⾃分らしく⾃由に経営ができる世界を ⽬指します。
そして、⽔やガスのように、意識せずとも当たり前に利⽤でき、⽣活(経営)を⽀える重要な存在、すなわち⾦融 インフラとなることを⽬指します。 freee finance lab は、これらをビジョンに掲げるfreee株式会社の100%出資⼦会社です。
freee finance labについて ⾦融開発部 カード開発A カード開発B 決済開発 freee 株式会社
開発組織 カード事業(biz) ⾦融事業 (biz) ⾦融BPR (ops) freee finance lab 開発組織は freee 株式会社本体に所属しているため、⽂化や 技術資産は共有している。本体との異動‧留学も可能。 事業部やオペレーションは freee finance lab に所属している。 いわゆる社内ベンチャーという形に近く、現在ではカード事業と決済事業を主軸に、 これまでも多くの新規事業の⽴ち上げをアグレッシブに⾏ってきた。
カード事業の取り組み
経営を強くする法⼈カード 「freeeカード Unlimited」を2021年にリリース 独⾃の ロジックで ⾼額与信 素早く freee会計へ 明細を同期
従業員の 利⽤統制
EKS Cluster 可⽤性を重視したマイクロサービスの初期導⼊ オーソリ 請求 与信 カード管理 通知 BFF
… Pod … Namespace EKS クラスタ上にGoで書かれたマイクロサービスを複数展開。フロントエンドはReactで、 BFFはfreeeのコード資産を活かすためRailsとなっている。これらをフルスタックに開発。
なぜマイクロサービス?
可⽤性を重視したマイクロサービスの初期導⼊ 従業員⽤カードを 100枚増やしたい ユーザーが店舗で決済 オーソリ (httpsリクエスト) オーソリ以外の⼤量のSQL 新たにカードを 申し込みたい
(N⼈) 共有された サーバープロセス 共有された データストレージ モノリスの場合 オーソリに関するSQL オーソリに応答できないと、ユーザーの決済が失敗してしまう。 DBやサーバーなどインフラを共有することでユーザーの決済に影響する。 ⼤量のトラフィック カード追加処理に伴う メモリリーク
可⽤性を重視したマイクロサービスの初期導⼊ 従業員⽤カードを 100枚増やしたい ユーザーが店舗で決済 オーソリ (httpsリクエスト) オーソリ以外の⼤量のSQL 新たにカードを 申し込みたい
(N⼈) 共有された サーバープロセス 共有された データストレージ モノリスの場合 オーソリに関するSQL オーソリに応答できないと、ユーザーの決済が失敗してしまう。 DBやサーバーなどインフラを共有することでユーザーの決済に影響する。 ⼤量のトラフィック カード追加処理に伴う メモリリーク マイクロサービスの場合 従業員⽤カードを 100枚増やしたい ユーザーが店舗で決済 オーソリ (httpsリクエスト) 新たにカードを 申し込みたい (N⼈) サーバーやDBを物理的に分離し、共有インフラの影響を回避する
可⽤性を重視したマイクロサービスの初期導⼊ カード情報 • アクティベート済みか • ⽉当たりの上限額 • 取引あたりの上限額 カード情報
• ステータス(アクティベート含む) • ⽉当たりの上限額 • 取引あたりの上限額 • PIN • カード番号の下4桁 • 有効期限など… • カードのアクティベート有無と上限額だけ知れればよい • アクティベート以前のステータスは知らなくてよい → カード情報の解釈が異なるため別々にモデリングする オーソリコンテキスト カード管理(申込〜発⾏)コンテキスト 境界づけられたコンテキスト (Bounded Context) 特定のモデルを定義‧適⽤する境界を明⽰的に⽰したもの。代表的な境界の例は、サブシステムやチームなど。 DDD Reference: https://www.domainlanguage.com/ddd/reference/ を和訳 業務ドメインの「関⼼の分離」によって、開発者はすべての業務ドメインを知らなくてもよい。 ⾔い換えると、DDDでは「結合‧再利⽤」よりも「重複」を好むとも⾔われる。
可⽤性を重視したマイクロサービスの初期導⼊ カード情報 • アクティベート済みか • ⽉当たりの上限額 • 取引あたりの上限額 カード情報
• ステータス(アクティベート含む) • ⽉当たりの上限額 • 取引あたりの上限額 • PIN • カード番号の下4桁 • 有効期限など… オーソリサービス カード管理サービス 境界づけられたコンテキスト (Bounded Context) 特定のモデルを定義‧適⽤する境界を明⽰的に⽰したもの。代表的な境界の例は、サブシステムやチームなど。 DDD Reference: https://www.domainlanguage.com/ddd/reference/ を和訳 マイクロサービスは、DDDのエッセンスを物理的設計に反映したものといえる。 関⼼の分離によるモジュール性の獲得で、組織が増えても開発はスケールすると実感した。 「アクティベート」など ドメインイベントを連携 オーソリ処理時に参照するための Read Model として永続化
事業拡⼤とともに開発組織は2倍に…
組織のスケーラビリティはどうだった?
プロダクトオーナー バックログ アイテム1 アイテム2 … … スクラムマスター ユニットA スクラムマスター
ユニットB スクラムの営みを⼀部合同で実施 全員でプロダクトの最適化を考える オーソリ 請求 カード管理 与信 全員でモノを考えて作る意味で、組織全体の結束感は⾼まった。しかし、 それ以上にコミュニケーションコストと認知負荷が⾼く、パフォーマンスに限界が⾒えた。 増員当初は LeSS (Large-Scale Scrum) をベースとした⼤規模なスクラムを運⽤ ⼤きなスクラムから⼩さなスクラムへ 担当ドメインは決めず 状況に応じてタスクを 分担し合う
スクラム マスター チームA スクラム マスター チームB 必要な時だけコミュニケーション スクラムイベントなどは個別実施 オーソリ
請求 カード管理 与信 コミュニケーションコストや認知負荷が⼤きく低減された。 幸い、LeSSによってチーム横断の⼀体感の下地ができていたため、サイロ化の恐れも少なかった。 次第に Scrum of Scrum に変更し、それぞれのチームを独⽴に成熟させる流れへ ⼤きなスクラムから⼩さなスクラムへ プロダクトオーナー バックログ プロダクトオーナー バックログ リード エンジニア リード エンジニア 担当ドメインを決め、 そのドメインに対して オーナーシップを持つ
そして、機能開発が並⾏するようになり…
以下の課題がベロシティに悪影響を及ぼした。 • ブランチ運⽤の煩雑化 • QAを実施する環境の不⾜ DevOpsの実践による開発速度の向上
以下の課題がベロシティに悪影響を及ぼした。 そのため、⼀時的にEnabling Team 的な遊撃隊を構成し、以下の取り組みを実施。 • ブランチ運⽤の煩雑化 ◦ → Feature
Toggleの導⼊ ◦ →トランクベース開発の導⼊ • QAを実施する環境の不⾜ ◦ → IaCのリファクタリングを伴う環境増築 DevOpsの実践による開発速度の向上
DevOpsの実践による開発速度の向上: IaCのリファクタリングを伴う環境増築 resource "aws_rds_cluster" "database" { + for_each =
local.environments - cluster_identifier = "database" + cluster_identifier = format("database-%s", each.value) engine = "aurora-mysql" ... } コード管理 コード管理 AWSリソースは Terraform によってコード管理。 社内 Terraform Module によって標準化。 kubernetesリソースは Helm によってコード管理。 社内 Helm Package によって標準化。 今まで単⼀の環境だったため、複数環境を考 慮していなかった。 そこで、IaCを全⾯的にリファクタリング。 プロダクト開発者⾃⾝の⼿で、⾃律的かつ迅 速に⾏った。
DevOpsの実践による開発速度の向上: Feature Toggle の導⼊ develop release 機能AのQA (QA環境へデプロイ) master
QA完了 タグリリース v1.1.0 feature/A feature/B 致命的な問題が起きたため 機能Bを先に出したい… 機能Aのrevert 機能BのQA merge & revert時の コンフリクトリスク 機能Aを先にリリース予定の場合、機能Bは本番に反映したくないため、featureブランチに退避していた。 ただし、開発が規模化するとコードコンフリクトのリスクが増える。また、リリース順序を組み替える際、 revertが必要になるなどブランチ操作が複雑化。デプロイのリードタイムに影響していた。 これまでのリリースフロー (Git-flowベース) → ステージング環境デプロイ → リグレッションテスト → 本番環境デプロイ 作業ブランチ
DevOpsの実践による開発速度の向上: Feature Toggle の導⼊ func (s *Server) CreateCard(ctx context.Context)
error { if featflg.Enabled(featflg.FeatureA) { // ONのときのロジック } else { // OFFのときのロジック } } デプロイとリリースを分離できるようになり、まだ本番で有効化したくない機能でも コード統合が可能になった。 --- feature_A: enabled: true expiration_date: 2023-04-26 team_name: Team B feature_B: enabled: false expiration_date: 2023-03-20 team_name: Team A yamlからフラグの状態を読み取る Feature Toggleとは、コードを変更することなくシステムの振る舞いを切り替える仕組みのこと。 その中でも、まずは 各機能のon/offを管理するための Release Toggle を導⼊。 既にfreeeの多くのプロダクトで導⼊されているが、Goの実績がなかったためライブラリを内製。 AWS AppConfigなども検討したが、まずはyamlでフラグの状態を管理するシンプルな形式でスタート。
DevOpsの実践による開発速度の向上: トランクベース開発の導⼊ main 個⼈の作業ブランチ release 機能A 機能B 1. 個⼈の作業ブランチを切って、mainにマージ。Release
Toggle を off にしてコードが発⽕しないように制御しておく。 機能Aの回帰テスト 機能B タグリリース v1.1.0 リリース順序の変更時にブランチ操作は不要になり、フラグの状態を変更するだけでよくなった。 頻繁にコード統合されることで、main が常に最新の状態を保てるようになった。 QAに必要なfeatureもコード統合された状態で main に存在するため、QA⽤のブランチは不要になった。 QA環境Xへデプロイ { A: on, B: off } とする 機能A ステージングデプロイ { A: on, B: off } 本番デプロイ { A: on, B: off } 機能Bの回帰テスト ステージングデプロイ { A: on, B: on } QA環境Yへデプロイ { A: on, B: on } とする 2. リリース前のコードスナップショットを release ブランチに退避し、短いスパンでマージする。
Enabling SRE によって⾃律的な開発組織へ Platform SRE Enabling SRE DBRE SRE組織
プロダクト開発チーム プロダクトA プロダクト開発者 プロダクトB プロダクト開発者 プロダクトC プロダクト開発者 Product SRE プロダクト開発者の中でSREの実践を率先できるメンバー(プロダクトSRE)を育成する。 freee finance lab では、各チームにプロダクトSREを1名ずつ任命。 クラスタのアップグレードなどの作業を委譲、特権ロールを付与し作業可能な範囲の拡⼤など。 プロダクトを載せる基盤 や仕組みを提供 DB運⽤のための仕組みや 知⾒を提供 プロダクト開発者にSREの知⾒ を提供‧サポートする プロダクト開発者の中で SREの実践に責任を持つ
Enabling SRE によって⾃律的な開発組織へ Platform SRE Enabling SRE DBRE SRE組織
プロダクト開発チーム プロダクトA プロダクト開発者 プロダクトB プロダクト開発者 プロダクトC プロダクト開発者 Product SRE • プロダクト開発の⽬線を知れる • SREの知⾒を提供できる 社内留学 • SREの知⾒を学べる • プロダクト開発の⽬線を提供できる 社内留学 SREとプロダクト開発者同⼠で相互留学をすることで、知⾒や⽂化を共有するムーブメント。 特に SRE→プロダクトの留学は Embedding SRE とも呼ばれる。 freee finance lab では早速受け⼊れを開始。
決済事業の取り組み
ラクで正確、安⼼、安価な 法⼈向け銀⾏振込サービスを提供予定 freee内で スムーズに ⽀払いが完結 安価な 振込⼿数料 独⾃技術で 誤り‧改ざん
を抑制 2023年内にfreee会計からの銀行振込機能を提供予定 国内の 銀行への振込をカバー | プレスリリース
カードの経験を活かすべく振り返り会へ…
マイクロサービスは成功だったか? 成功だったポイント • 可用性・耐障害性 ◦ オーソリを物理的に分離かつ疎結合にしたため、他サービス依存の決済障害はほぼ起こらなかった。 • モジュール性・開発のスケーラビリティ ◦
業務ドメインによる関心の分離によって、開発が並行・規模化しても独立して開発可能。 ◦ 新メンバーが増えたが、1つの業務ドメインおよびマイクロサービスから独立して学べた。 • 幸い分散トランザクションが不要だった ◦ 一般的には、マイクロサービスで最も大きな課題になる。 ◦ 粒度は「集約(=整合性の単位)より大きく、コンテキスト境界より小さく」が良いとされる。 ▪ 集約より小さく作ってしまうと、複数のMS間で1つの整合性を維持することが必要に…。 ▪ コンテキスト境界より大きく作ってしまうと、1つのMS内でモデルの定義がブレる。 ◦ ドメイン分析をしっかりしていたため、MSの粒度設計を間違えなかった。 ◦ また、ドメイン間でトランザクションのライフサイクルも異なっていたのも大きい。 ◦ (リアルタイムなオーソリ、毎月決まった日付に処理する請求、ユーザー申込時の与信など) • 一般的に、他にはデプロイ容易性・弾力性・進化性といったメリットもある。 しかし、どんなアーキテクチャにもトレードオフがある
マイクロサービスは成功だったか? 失敗だったポイント • 複雑性(マイクロサービス間の連携) ◦ SQS + SNS のFanout
PatternでProducerがConsumerを意識しない形にしたが、逆に無意識に多くの依存 が生まれていた。依存関係の把握が難しい。 ◦ SNSへのメッセージ配送とSQLを同一txnで扱うため、Outbox Patternを導入 ◦ メッセージの重複処理を排除するため、Inbox Patternを導入 • 動作確認が難しい(テスト容易性) ◦ 基本的に1つのマイクロサービス内で完結するが、ユースケースによっては複数起動が必要 • インフラの管理コスト・料金コスト ◦ 環境 ✕ マイクロサービス分だけインフラが必要 ◦ IaCコードの書き方で工夫しているが、それでもメンテコストがかかる • 可観測性 ◦ 社内の分散トレーシングは進みつつあるが、サービス間のやりとりを追いかけるのは少し難しい 可⽤性が必要だったオーソリ以外は物理的分離である必要はなく、 論理的分離でモジュール性‧スケーラビリティを獲得することはできなかったか?
デプロイ単位 モジュラモノリスで⼩さく始めるドメイン分割 照合 モジュール 申込‧審査 モジュール ワークフロー モジュール 振込
モジュール ✕ 名前空間やパッケージで表現するため 再設計が比較的容易 ◯ あるべき依存関係を定義し、相互参 照・循環参照を禁止する メソッド呼び出し 法人間の振込業務では、即日の振込はあれどカードのオーソリほどのリアルタイム性は求められない。 これを踏まえて、モジュラモノリスを採用してみることにした。 モジュラモノリスでは、論理的分離でマイクロサービス同等のモジュール性の獲得を目指す。 こうしたアプリケーションレイヤーの設計は軌道修正が比較的容易で、ドメイン分析に不安があっても後戻り しやすい。逆にいうと、設計の強制力が弱いため、依存関係の違反をlintで禁止する。
モジュラモノリスで⼩さく始めるドメイン分割 他モジュールを参照できるレイヤーの制限 データに対する排他的所有権 domain domain module A ◯ ✕
✕ ✕ 一番外側のレイヤー同士のみ依存できるようにする。例えば domain層同士が依存するとドメイン分割が無意味になる。 module B 申込 ワークフロー 申請 取引 ⽀払先 法⼈情報 代表者 審査 DBは単一なので、モジュール間でデータモデルを介して 密結合になる可能性がある。排他的な所有権を定める。 Shopifyの事例 (*) を参考に、「まずは取り入れてみて考えよう」という気持ちで進めている。 (*) Shopify Engineering「Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity」
突き詰めながらも、挑戦や遊び⼼を 「プロダクトの特性・組織の事情を抑えながら、価値ある技術的チャレンジをする」 • フロントエンドにおける vite の採用 ◦ 最近では Next.js
や Astro のように多様なレンダリング方式・最適化・開発体験を提供するFWが登場 ◦ 一方、ログイン前提の機能がほとんどで「静的な海」は少ないため、CSRが落とし所になる ◦ そこで、開発者体験に焦点を置き、 vite を採用するに至った。 • playwright codegen の採用検討 ◦ 開発者自身が e2e をメンテナンスしやすいように selenium による e2e 基盤からの移行を検討 • sqlc の技術検証 ◦ SQLから構造体やデータアクセスロジックなどのボイラープレートコードの自動生成が可能 • など… 新規プロダクトだからこそ積極的に取り組んでいく
さいごに そんなフルスタック‧フルサイクルな開発組織で、 スモールビジネスを主役にする「⾦融インフラ」を実現したい 仲間を募集しています。 カード事業エンジニア 決済事業エンジニア
None