2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
Payment as a Microservice(全1記事)
提供:PayPay株式会社
リンクをコピー
記事をブックマーク
Harsh Prasad氏:みなさん、こんばんは。PayPayのペイメントコアシステムを担当している、プラサド・ハーシュと申します。今日お話しさせていただきたいことは、ペイメントマイクロサービスとして提供しているバックエンド・フロントエンドのどこに課題があるか、どんなことを改善しないといけないかを説明させていただきます。
簡単に自己紹介をすると、2013年にインドのIIT(インド工科大学)を卒業して、Yahoo! JAPANに2014年に入社しました。趣味は撮影と旅行とハイキングで、肉大好きな人です。
今日話したいこととして、まずは、なぜマイクロサービスを選択したか。そしてペイメントプラットフォームアーキテクチャの説明もさせていただきたいと思ってます。あとは、現在分散システムを使ってるので、そのシステムの課題と、整合性の問題をどのように強化するか、大量のリクエストが来ても正確な処理をするために、どのように対応すればいいか。こういったことを話していきたいと思ってます。
まず、「なぜマイクロサービスなのか?」についてです。マイクロサービスがいくつもあると、失敗する箇所も増えていきます。また、エラー処理や管理がひどくなるとも言われています。
ですが、マイクロサービスの場合、大規模のService-Oriented Applicationsシステムを分散サービスとして提供すれば、そういった課題はなくなります。
逆に、決済処理のそれぞれの部分を独立して動かすこともできますし、開発スピードとリリースも早くなるので、一部のマイクロサービスだけをすぐに更新して、ほかのところに影響がない状況を確保することもできます。
あとは、マイクロサービスが古くなったりあまり使いたくなくなったときには、すぐ捨てることも可能です。各マイクロサービスの役割と開発者の役割が分散するので、マイクロサービスアーキテクチャのほうが快適だと感じています。
現在、決済だけをちゃんと同期させたいと思ってるんですが、決済に関係ないとこが決済に影響しないように、別のマイクロサービスで動かすことも可能です。
また、いろいろなビジネスコンテキストに応じて開発が可能です。新しいマイクロサービスをどんどん追加して、新しい機能もどんどん提供できるようになっています。こうしたマイクロサービス開発を行いながら、いろいろな分野について知っている人と、ビジネスコンテキストを理解している人で、Smart, Cross Functional Teamが誕生しました。
続いて、PayPayのペイメントプラットフォームアーキテクチャについてお話しします。
こちらの画像のように、いろいろなコンポーネントがありますが、15個以上のマイクロサービスはペイメントのプラットフォームアーキテクチャの中に入っています。
それぞれ説明すると15分では足りないので、簡単に説明したいと思ってます。
まず、トランザクションシステムというマイクロサービスが先頭にあります。これは、決済のリクエストを受け取るコンポーネントです。トランザクションシステムの役割は、取引番号の発番をしたり、二重決済の監視やエラー処理、冪等性(べきとうせい)の管理などを担っています。
あとキャッシャーというコンポーネントは、一応ステートは持ってないコンポーネントです。この決済やこの取引は進んでいいのかを判断しています。ユーザーの履歴やほかのところもすべて確認して、「この取引で進めていい」という判断をしたら、ペイメントシステムに決済のリクエストを流してウォレットからお金を動かしたり、銀行やクレジットカードシステム、外部のウォレットなど、さまざまなサービスと連携して、ちゃんと決済が完了できるようにしてます。
決済に直接関係がないところは、すべてメッセージキュー経由で情報を得て自分のビューを作るなど、それぞれの役割を果たしてます。
例えばリードビューというコンポーネントは、決済履歴を作るコンポーネントです。現在、それぞれのマイクロサービスは自分のデータベースを持ってます。そのため、決済に関する情報がいろいろなマイクロサービスに分散しているので、それを全部収集・集計してユーザーに表示しなければいけません。
そのために、リードビューというシステムが、さまざまなマイクロサービスからイベントを収集して、ユーザーに見せたい情報を集計して、DBに書き込んでます。
同じくマーチャント、振込システムも直接DBから情報を引っ張ってくるのではなく、Kafkaのメッセージキューのイベントを使っています。過去のマーチャントに対して、いくら振り込むべきか、いつ振り込むべきか、独立して動くようにできてます。
一平さんが説明したキャッシュバックシステムと同じく、決済が走ったらそれぞれのイベントを収集して、何をいくら付与したらいいか、全部判断できます。
これを全部、ペイメントがプラットフォームを通して提供すれば、その上でいくつもの新しいフィーチャーをどんどん追加しても、ペイメントのAPIだけを叩いて新しい機能の追加ができます。
例えば銀行からのチャージも、ペイメントとしては何も修正せずに新しいフィーチャーとして提供したら、「この銀行からチャージしたい」にCDだけ出せば、全部うまく動くと思います。
ですが、いろんな分散システムを使っていて、課題もいくつか存在しています。一番大きな課題は、データの整合性の担保です。マイクロサービスAでは情報は正しく整理されているものの、マイクロサービスBはそれ知らないとか、エラーが発生してもちゃんと処理できないといった問題があります。
あと、1つの決済に対して数十個のマイクロサービスを通して決済を完了しないといけないんですが、E2Eテストだと正常ケースはけっこう速めに、簡単にできるんです。ですが異常のテストは難しくて、いろいろなコンポーネントで異常が発生する可能性があるのか、テストの自動化はけっこう大変です。
マイクロサービスのデザインパターンとして、イベントソーシングで非同期のメッセージを収集して、それでビューを作ったり、ほかの処理をしています。イベントソーシングのリライアビリティについてはKafkaを使ってるんですが、Kafkaでメッセージがなくなったり、Kafkaにバックできなかったり。そういったところを検知していかなければ、不整合が起こってしまいます。
非同期処理でもいろいろなことが発生します。例えばペイアウト、マーチャントで振込しているところも非同期で全部やっているのですが、それがちゃんとマーチャントに振込できたかどうか、その正確性も確認しなければいけません。そのため、整合性の強化が必要になってきました。
まずデータの整合性を強化するために、必ずペイメントシステムとして持っていなければいけないのは冪等性です。
ペイメントシステムの中にはいろいろなマイクロサービスがありますが、すべてのマイクロサービスが相互に突合を行っています。突合はreconciliationとも言いますが、マイクロサービスBにあるステートとマイクロサービスAにあるステートが一致しているかどうかを必ずチェックしなければ、いつか絶対に不整合が出てしまいます。
そのため、ペイメントシステムとしても、リアルタイムの突合を行っています。また、1日とか半日のバッチで定期で突合をやっていて、情報の状態がずれてないことを確認しています。ずれていたら補償トランザクション、compensationですべての情報のステートと状態が正しくなるようにしています。
compensationについてですが、いろいろなマイクロサービスが他のマイクロサービスや外部のサービスと連携をしていますが、その際に、タイムアウトが発生する可能性があります。外部サービスの不具合によってもタイムアウトが発生する可能性があるので、その際にすべて手動で対応するのは難しいです。そのため、各マイクロサービスがこの補償トランザクション、compensationを持って、次の層までこのcompensationの取引を渡せるような仕組みを持ってます。
ペイメントシステムやトランザクションシステムに何かあったら、トランザクションシステムが補償トランザクションを使って、ペイメントシステムまで渡す役割を持ってます。ペイメントシステムが受け取ったらトランザクションシステムの役割が終わって、ペイメントシステムがそれをウォレットまで渡します。また、エクスターナルサービス、外部のサービスにも渡す役割を持ってます。
こうした仕組みによって簡単に、それぞれのマイクロサービスが補償トランザクションを提供しておけば、自動で不整合をなくすことが可能です。
現在、ビジネス側でもいろいろな企画を行っていますが、キャンペーンを行った際などに、大量のリクエストがいきなり発生することがあります。それらの突発的なリクエストに対して、いちいちシステムが安定しているか、システムが耐えられるかどうかを確認するのは難しいので。そのため、いきなり大量のリクエストが来てもシステムが正確に処理できるような仕組みを作りたいと考えています。
もちろんロードバランサーやCDCR(Cross Data Center Replication)などは必須です。複数データセンターとアベイラビリティゾーンに同じ情報を同期しています。これのもっとも重要でおすすめなのが、Fail Fastやサーキットブレーカーを使うことです。
サーキットブレーカーは、決済が失敗したりタイムアウトしたり、そういった異常を各マイクロサービスが自分で検知するようにしています。マイクロサービスBは今は反応が悪い、という場合はすぐに折り返して、リクエストがすぐに失敗するようにしています。
システム全体が死んでしまうと、決済も何も、ほかのことができなくなってしまうので、すぐに折り返すことは重要です。1つのマイクロサービスが使えなくなったとしても、そのマイクロサービスにもうリクエストを送らないようにすることで、相手のマイクロサービス側に復活する余裕が生まれます。そのため、サーキットブレーカーを必ず、ほかのマイクロサービスと接続してるところに入れています。
あとは、決済に必要なものだけ同期して、それ以外の処理はすべて非同期にしています。ユーザーの数値や補償トランザクションでリカバリーしたことを周知するものも、非同期でやっています。ペイアウトもユーザーのビューやペイメントでできることを作るときも、すべて非同期でやっています。
そして、決済は高速で実行できなければいけません。今この瞬間に各ユーザーがレジをしていて決済が5秒かかってしまうと嫌になりますし、後ろの人も待たせてしまいます。そのため、決済自体を早く終わらせなければいけません。
現在、ユーザーの履歴を作ったり、ほかのところを見せるために、DBにインデックスを追加しています。ですが、インデックスが入ったら各取引にも影響があるので、冪等性の必要があるインデックスだけに追加して、それ以外のインデックスはread用の別のスレーブのデータベースに追加したほうが良いです。これなら決済を早く終わらせることができるので、ユーザーも楽しくPayPayを使えるのではないかと思います。
そして冪等性があれば、クライアント側でリトライしてもらってぜんぜん問題ありません。クライアントで結果が返って来ないからあとでリトライすれば、失敗になっているか成功になっているかがわかります。クライアント側には少し負担がかかりますが、リトライしてもらったほうがいいと思います。
そして処理できない場合は、補償トランザクションやcompensationが必ず走るんですが、「お金が銀行にもないしPayPayにもない」といったことがあるとユーザーも困ってしまうので、必ずユーザーへ通知を行っています。
以上です。ありがとうございました。
(会場拍手)
PayPay株式会社
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05