Bonfire Backend #3 - connpass
Yahoo!主催の勉強会に参加してきました。今回は「ブログで感想枠」として抽選無しで参加させて頂いています。テーマが「モバイル決済の裏側」で自分がやっている領域にもちょっと近いためかなり楽しんできました。



<Origami Pay開発苦労話>
亀井浩明さん ◆ 株式会社Origami
2015-08-01入社、Engineering Group Manager

Origami Payを開始したのは2015年10月、8月入社の段階ではほとんど完成していた、今回はサービス開始後に焦点を当てる。

・サービス開始後
当時はそもそもスマートフォンで支払いを行うというサービスがなかった。
リリースしても決済が起きない。問題が発生したかもわからない。
-> 自分達でカフェに行って待機、リリース完了後に購入
今は社内売店で本番確認。今でもpos経由だったり大きな加盟店経由なら実テスト。

・基本的な仕組み MPN
1 加盟店が金額入力し支払いコード発行
2 お客様が支払いコードを自分の端末に入力
その入力方法に制約はない

・入力方法
* 手で入力 (カメラが壊れている場合にも使える)
* iBeaconを使う (今は廃止)

・iBeacon
BLE規格。接触しないで決済できるが、受信状況がかなり不安定。
機種によっても発信源の位置が違う。
だんだんiBeaconの電波が見えてくる
iBeaconとQRどっちがいい?を考えてQRになった。
初期の頃からQRコード決済はあり、徐々にQRコードへ。
QRコードは失敗した時も原因がわかりやすい。





<Kyashの今とこれから 〜Walletの学びとDirectへの挑戦〜 (仮) >
松田 優貴さん ◆ 株式会社 Kyash
@yumatsud
2018-04までyahooにいた。
テックリード、スクラムマスターなど

・kyashについて
特徴的な点はvisaカード、多彩なチャージ
もう1つの事業としてkyashのAPIを利用企業に開放している。
カード発行、決済、チャージをパートナー企業が使えるようになる。

・Kyash Server Sideのいま(ウォレット事業の話)
各システムはマイクロサービス化され、カード発行、チャージ、通知、認証、家計簿連携、etcに分かれる。
(マイクロサービス間の通信は同期)
アプリからの通信と、VisaNetからのリクエストをEC2経由で受けとる。

・Visa決済について
加盟店からアクワイアラを経由し、visaにいく
やる事は、仮売上処理、売上確定処理、清算処理 etc
これをvisa特有のメッセージ(電文)でやり取りをする。英語でトータル1000ページとかある。
サーバーはGo。
数秒でレスポンスを返す必要がある

・内製したからできる事
* 利用履歴
* 自動チャージ
* リアルタイム通知
など

・課題
履歴は各マイクロサービスに分散している
APIが肥大化してきた

・これから
kyash directを開発中(なのでこの形になるかわからない)
* CQRS
更新系と参照系にシステムを分ける
履歴の作成が分散&責務多寡になっているのを解決したい
それぞれの取引処理は各サービスで処理した上で、表示するためのものはQueryで処理

* Choreography
マイクロサービス間のやり取りをを使い非同期に連携
Eventによるメッセージをやり取りする
キューイングはSQS、イベントを投げるとそのイベントに興味があるサービスがそのイベントを受け取る。マイクロサービス間では通信しない。
メリット 完全に非同期にできる, 処理を小さくできドメインロジックに集中できる
デメリット デバッグが大変, Eventの順番がずれると整合性が取れない





<静的QRコード(MPM)決済を支える技術>
susho(@@susho0220)さん ◆ 株式会社メルペイ
すしょーさん
2018年までyahooでオブジェクトストレージDragonを開発

静的MPM決済を支える技術 / #yjbonfire - Speaker Deck

・静的MPM
店舗側にある固定のQRコードで決済する方法のこと
物理的な改竄防止もしている。
6/27にリリース。
仕様は、技術団体EMVCoが策定した共通規格EMVを利用。
 2017年8月に発表?EMVCoによるグローバルなQRコード決済仕様に対応(Visa) « ペイメントナビ - カード決済、PCI DSS、ICカード・ポイントカードの啓蒙ポータルサイト
EMVのQRコードのエンコード、デコードは自社開発

・構成概要
GCP
API Gatewayにリクエストを受け、gRPCへプロトコルに変換、ルーティング、認証を実施
認証サービスが認証tokenを生成、これは全てのマイクロサービスが検証する
QRコードを解釈、店舗IDを取り出して店舗情報取得、決済処理、通知、などが独立して存在

・決済シーケンス
アプリからリクエストがあると、セッションを生成し店舗情報と共にクライアントに情報を返す
アプリで金額を入力すると、決済リクエストが飛び、セッショントークンの検証と決済を行う

・MPMサービスでやること
* QRコードの解釈
https://github.com/mercari/go-emv-code
今後拡張される可能性があるのでサーバーサイドで解釈している
* セッショントークン管理
一定期間放置されたら決済できなくする
* トランザクション管理
こちら マイクロサービスにおける決済トランザクション管理 - Mercari Engineering Blog

・不整合対策
* 冪等性
同じリクエストには同じ結果が帰る
クライアントがuuid(idempotency key)をリクエストに付与して区別
* Write repair
マイクロサービス間で一時的な障害があっても、リトライして不整合を修復する
grpc_retry grpc_retry - GoDoc
* Asynchronous rpair
write repairで修復できなかった場合に非同期に修復

・Write repair
決済リクエスト開始時にidempotency keyの発行とDBトランザクションへ開始(initialという状態を定義)
そこで書き込めなかった場合
クライアントにてタイムアウトを検知し、同じkeyのものを再度実行させる

・Asynchronous repair
一定時間起き?DBトランザクションが開始しているがそのままになっているものを検知し修復

これらをマイクロサービスそれぞれに実装が必要になる
ネットワークの分断を再現するのが大変
iptablesで擬似的にパケット遅延させたりしても大変

・今後
Envoy導入、これによりテストもしやすくなる

・メモ
Idempotency Key Patterns of Service-oriented Architecture: Idempotency Key | Stitch Fix Technology – Multithreaded





<100億を支える技術>
正木 一平さん ◆ PayPay株式会社
yahooから出向
キャンペーン、キャッシュバックエンジンの話など
週一スプリントのアジャイル、10ヶ月でアプリを50回リリース
外国籍のエンジニアが40%以上

・マイクロサービス
60以上のサービス、7以上のチームで開発。それぞれのサービスが独立したリソースを持つ
APIやkafkaで通信

・キャンペーン
沢山のキャンペーンが動いている、常に40-50とか動いている。
決済完了画面においてキャンペーンに対応した付与額と付与予定日を表示しているので、そこまでに処理を完了しないといけない
キャンペーンにも条件がある、加盟店情報、ユーザー情報、支払い上限etc
もしキャッシュバックエンジンが故障していても決済はできないといけない

そこでイベント駆動で非同期、インターフェースはKafkaのみ
kafkaは分散ストリーミング、順序づけを保証しつつ負荷分散もできる
他のサービスはkafkaにイベントをpublishすればいい。キャッシュバックには関心を持たない
キャッシュバックエンジンはkyashからサブスクライブされた内容を見る
scala + akka streamを採用
akkaは分散・並列処理を実装可能(低レベルなマルチスレッドプログラミングをしないで)
リアクティブシステムを必要とする環境に適している
 即応性、耐障害性、弾力性、メッセージ駆動(非同期)
キャンペーンシステムにはまさにこういうことが求められている

・Akka Streams
reactive streamsの仕様に準拠
 ノンブロッキングなback pressure(イベントを受ける側のsubscriverが、イベントを投げる側のpublisher側に処理できる量を伝えることをできる)可能な非同期処理の仕様のこと

・現行システムの利点
新しい環境に一部イベントだけ流すこともでき、そこでテストしてそのまま移行も可能
他のサービスに依存していない
amazon rdsからamazon auroraへのマイグレーションをするときも、kafkaのイベントを受けるのを一部止めて、その間にDNSを切り替えた。メンテナンス不要

・課題
ユーザー数が増えてきたのでチューニングが必要になってきた
akka内部のパフォーマンスを可視化してボトルネックを探していく




<Payment as a Microservice>
Harsh Prasadさん ◆ PayPay株式会社
テックリード、2014年からyahoo。

・マイクロサービス
マイクロサービスが増えていくと失敗する可能性がある箇所も増えていく、それによりエラー内容も複雑になっていく
それを分散サービスとして独立させていけば、そういった課題は解決できる
開発とリリースも早くなる
役割分散も可能、不要になったら捨てることも可能
決済に影響させず、決済に関係ない部分の開発も可能
ビジネスコンテキストが増えたらマイクロサービスを増やす

・payment platformの世界
トランザクションシステムがまず受けて冪等性や整合性の管理
その決済を進めていいか判断し、決済システムに流す
それぞれのマイクロサービスがそれぞれDBを持っているので、それらのデータを集めるマイクロサービスを用意

・分散システムの課題
データ整合性の担保が難しい
* マイクロサービスごとに知っていることが違う、エラーの管理
* 1つの決済に対して多数のマイクロサービスが動く時の異常テストが難しい(そのテストの自動化が大変
* イベントの不整合検知
* 非同期処理の正しさの確認

・整合性の強化が必要
* 必ず冪等性が必要
idempotency。同じリクエストが何度きても同じ結果を返す
* マイクロサービス間の突合
これをやらないとずれてないことを確認できない
リアルタイムのほか、定期的にも実施している
* 補償トランザクション
不整合発生時に対応する
外部サービスとの連携や相手の不具合もある
そういう時に手動でやるのは難しい、各トランザクションがそういったことに対応
自動で不整合をなくす

・対象のリクエストへの対応
Fail Fast(サーキットブレイカー)、決済の失敗を検知してリクエストをすぐに失敗にさせる
1つのマイクロサービスが死んでも他に影響を出さないようにする
決済に必要なものは同期、他は非同期
(ここ多分) 冪等性に必要のあるindexをmasterに追加、それ以外はslaveに追加?
問題があればクライアント側でリトライ
処理できない場合はクライアントに通知