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
Restate x Stripe: 安心して眠れる決済システムを目指して
Search
acomagu
November 07, 2025
16
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Restate x Stripe: 安心して眠れる決済システムを目指して
acomagu
November 07, 2025
More Decks by acomagu
See All by acomagu
Payment Records API を使って地域通貨を Stripe Dashboard に統合してみた
acomagu
0
62
Stripe SSoT をするべきか否か
acomagu
0
83
JP_Stripes: リコンサイル(突合処理)のテスト
acomagu
0
130
「境界付けられたコンテキスト間の関係」についてもっと語ろう
acomagu
0
170
地方 MaaS 事例: アプリの進化に伴って変化してきた Stripe 利用方法
acomagu
0
510
Stripe リコンサイルの勘所
acomagu
0
540
CDK 一発で全てのエラーログを Slack に流す
acomagu
0
2.3k
AWS CDK を支える Constructs について
acomagu
0
190
DDDとは結局何なのか
acomagu
0
450
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Mobile First: as difficult as doing things right
swwweet
225
10k
Google's AI Overviews - The New Search
badams
0
1k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
320
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Are puppies a ranking factor?
jonoalderson
1
3.6k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
210
HDC tutorial
michielstock
2
720
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
420
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
New Earth Scene 8
popppiees
3
2.3k
Transcript
Restate x Stripe 安心して眠れる決済システムを目指して @acomagu 2025/11/07 「JAWS-UG会津」&「JP_Stripes会津」合同勉強会 2025 Autumn
Stripe を使っていると Event Sourcing に惹かれる なぜか? - Stripe Webhook がそのままイベントとして使えるから
- 決済システムは不整合が許されないから - Event Sourcing を使うことで、「真となるデータ」を1箇所(Event Store)に集約することができ、各 サービスはそこから状態を計算することに集中すればよくなる
なぜ Event Sourcing は世界を席巻していないのか A: 大変すぎるから Event Sourcing を導入するには:
- 全ての副作用を冪等(リプレイ可能)にする必要がある(External Updates 問題) - 全ての外部からの情報取得の結果を記録しておく必要がある(External Queries 問 題) - ドメインロジックの時間的な変更履歴を全てドメインロジックに組み込む必要がある (Code Changes 問題) e.g. 11月まではメール通知をしていなかったが、12月からはメール通知をすることになった - Event Sourcing を導入すると、ユーザーからのリクエストに対して「同期的に処理を 実行し、その結果を即座にレスポンスする」ということが簡単ではなくなる
↑Stripe からのイベントだけ考えれば上記のような形でうまく行きそうだが... - 例えばメール送信はどうやって冪等関数にするのか? - 例えば金額を外部 CMS から取得しているとしたら、「その時点での金額」をどうやって記録しておくの
か? (大体 External Gateway パターンを使って副作用の入力と出力を記録することになるが、通信するシステムが 多い場合これがかなり大変になってくる上に、Gateway 自体のバグ修正が難しい)
Restate とは?
Restate とは? Stephan Ewen, the creator of Apache Flink
Restate 誕生物語 Source: https://www.restate.dev/blog/why-we-built-restate
Restate 誕生物語 Source: https://www.restate.dev/blog/why-we-built-restate やってやったぜ! うーん...
Restate 誕生物語 - Stephan は、Flink の顧客とコミュニケーションを取る中で「Flink は分析用途には合 うが、よりトランザクショナルな用途のアプリケーションには合わない」と感じていた - しかし、依然としてトランザクショナル界隈の書き心地はひどい
- なので「ストリーム処理の魔法のような回復力とスケーラビリティ」と「RPC のシンプ ルさと柔軟さ」の2つの世界の橋渡しをするフレームワークを作ることに決めた - つまり、Restate は RPC のように書けるのに、 Event Sourcing のようにイベントドリ ブンに実行されるフレームワーク
いいからコードを見せろ!
Restate の機能 メインは二つのみ 副作用の冪等化 トランザクション分離
Restate の機能 メインは二つのみ 副作用の冪等化 Durable
Step トランザクション分離 Virtual Object Workflow
Restate の機能 メインは二つのみ 副作用の冪等化 Durable
Step トランザクション分離 Virtual Object Workflow
副作用の冪等化 Durable Step: ctx.run で囲むことで、結果が保存されるようになる → 何度実行しても同じ結果が得られる
副作用の冪等化 Durable Step: ctx.run で囲むことで、結果が保存されるようになる → 何度実行しても同じ結果が得られる
→ 何度実行しても関数内は1度しか実行されない
副作用の冪等化 Durable Step: ctx.run で囲むことで、結果が保存されるようになる → 何度実行しても同じ結果が得られる
→ 何度実行しても関数内は1度しか実行されない ただし、失敗(throw)した場合は、結果は保存されない
副作用の冪等化 Durable Step: ctx.run で囲むことで、結果が保存されるようになる → 何度実行しても同じ結果が得られる
→ 何度実行しても関数内は1度しか実行されない ただし、失敗(throw)した場合は、結果は保存されない → 失敗した ctx.run は、次回再実行される
Action, Handler, Service Action Handler Service
Action, Handler, Service Action Handler Service ハンドラはリトライのために複数回実行される! (ただし成功した ctx.run
は結果がメモ化される)
Restate の機能 副作用の冪等化 Durable Step
トランザクション分離 Virtual Object Workflow
トランザクション分離 Service は3種類あるが、そのうち Virtual Object と Workflow がトランザクション分離の 機能を持っている。
Virtual Object / Workflow 共に 「キー(string)で分離し、キーごとに直列に実行される」分離方法
トランザクション分離: Virtual Object Virtual Object(Service)
トランザクション分離: Virtual Object Virtual Object(Service) userId ごとにキューがで きるイメージ
トランザクション分離 Service は3種類あるが、そのうち Virtual Object と Workflow がトランザクション分離の 機能を持っている。
Virtual Object / Workflow 共に 「キー(string)で分離し、キーごとに直列に実行される」分離方法 Virtual Object と Workflow の違い: - Virtual Object: 全てのメソッドが何度でも呼び出せる - Workflow: run メソッドが必要で、このメソッドは1回だけ呼び出される Durable Promise(ctx.promise)が利用可能
トランザクション分離: Workflow
トランザクション分離: Workflow Promise を待っている間 ずっと関数が実行中なわ けではない。 Promise が Resolve さ
れたタイミングで、run メ ソッドが再開される
これらを使った Stripe Demo https://gist.github.com/acomagu/fc473bcd1a7ddce002a210fe10b89e2e
これで安心して眠れるね!
ほんとに?
重箱の隅①
本当に Restate を使うだけで分散トランザクションは安全なのか A: 間違い Restate は、「安全なシステムを作りやすくする部品」を提供しているが、「デフォルトで安 全になる」わけではない。
分散トランザクションと言えば... - Saga - 2PC
Saga と比較してみる Saga では、トランザクションは3種類に分類される: - リトライ可能トランザクション - 補償可能トランザクション - ピボットトランザクション(今回は考えません)
Restate で ctx.run を使うだけでは、「リトライ可能トランザクション」しか面倒を見てくれな い!
Restate + Saga Source: https://docs.restate.dev/guides/sagas
結局 Saga やるなら Restate 要らなくない? A: Restate を使うことで Saga をシンプルに実装可能になる
最も素朴な Saga の実装では、ACID のうち「原子性」しか担保できず、「永続性」や「分 離性」「整合性」を満たしません。(整合性については議論あり) しかし、前スライドのコードのように Restate 上で Saga をするだけで、「永続性」「分離 性」を満たすことができます。 永続性: ハンドラや Restate Server が落ちても、自動で中断した Action から再開されま す 分離性: Virtual Object や Workflow を使うことで実現できます
重箱の隅②
ctx.run はガチで絶対1回しか実行されないの? (リトライ除く) A: 嘘です Restate のドキュメントでは「かなり稀なケースなので通常は起こらないと想定可能だ が、理論的には ctx.run
内部の関数が成功したのに2度目が実行される場合がある」と の記述があります。 つまり、ctx.run() の結果を Restate Server に送る瞬間にクラッシュやネットワーク断が 起こった場合です。
ctx.run の2度実行に備える方法 3つあると考えています: 1. 関数内を冪等にする a. ctx.run 内で外部サーバーに送る際に Idempotency Key
を使う等で複数回実行されても安全にしま す 2. 2つの ctx.run を使って 2PCにする a. 1つ目の ctx.run で Prepare し、2つ目でコミットすることで、2つ目だけが複数回実行されることが あっても1度のコミットになります b. RDBMS だとラッパー関数を使って簡単に実装できます 3. read / write を別の ctx.run にして、Virtual Object を使って Isolation する a. これは「関数内を冪等にする」に近いですが、 SET credits = credits + 100 のようにするより、read / write を別の ctx.run にすることで、2つ目だけリトライされても同じ値で上 書きされるようになります。 また Isolation によって、その Virtual Object からのみ credits を触っている限り、不整合は起こりま せん
まとめ ① Restate は「シンプルな RPC の書き心地で」「イベントドリブンなアーキテクチャの安 全性を達成できる」フレームワークです。 ② Restate
は ctx.run によって「副作用の冪等化」を、Virtual Object と Workflow で「トラ ンザクション分離」を提供します ③ Restate で ctx.run を使うだけで自動で Saga や 2PC になるわけではなく、デフォルト ではリトライのみ面倒を見ます。しかし、Restate 上で Saga や 2PC を実装すると、簡単 に更に堅牢なコードを実現できます。