builderscon tokyo 2019 Aug 30
builderscon tokyo 2019 2日目(8/30)の参加レポート(メモ書き)です。
builderscon tokyo 2019
会場
東京電機大学 (東京千住キャンパス)1号館
メインの大きいホール(丹羽ホール)の様子
会場まわりの細かい情報
- メインの大きいホールには各席ごとに電源コンセントがある
- 大きいホール以外はわりと狭いので満席になりやすい
1階にあるA, Bホールはすぐ満席になってました - Wi-Fiは登録制、受付で規約に同意してリストに名前を書くとID/PWの紙をもらえる、全員分はなく限りがある
参加したセッション
- Open SKT: メルペイ開発の裏側 - builderscon tokyo 2019
- RDBのトラブルの現場を追え! - builderscon tokyo 2019
- WebAuthn/FIDOのUX徹底解説 ~実サービスへの導入イメージを添えて~ - builderscon tokyo 2019
- ソースコードを堪能せよ - builderscon tokyo 2019
- ウォレットアプリ「Kyash」の先 〜「Kyash Direct」のアーキテクチャ〜 - builderscon tokyo 2019
Open SKT: メルペイ開発の裏側
メモ(≒スライドの内容)
決済金融サービスは難しい →トランザクション管理 →他にも難しいことはある メルペイ開発 →安定して信頼できるシステム →サービス開発をメインにしない アーキテクチャ →GCP、GKE 4階層アーキテクチャ クライアント、API Gateway、API Service、バックエンドサービス API Gateway: リバースプロキシ的な役割 APIサービス: バリデーション、BEサービスのアグリゲーション、クライアントの互換性、ABテスト、レスポンスを返す BE: 担当ドメインに特化した機能 分散システムにおけるトランザクション →難しい →メルペイではどうしているか 支払い方法が複数あり複雑、組み合わせも自由 エラー処理を含めたモデルの一般化 →お金の足し算は失敗しない、引き算は残高がないとできない →リトライと冪等性 →どんなエラーが出ても基本的にリトライする →冪等性を担保して二重処理されないようにする →継続不可能なときのみ処理をやめる 引き算 →Try/Confirm/Cancel →確認と確保、確定、開放 状態遷移によるトランザクションコーディネーション 会計の話、リコンサイル、整合性/一貫性の確認、生産 →難しい・・ お金に関する不正検知 →ログイン、入金、出金 メルペイができたことにより変わったところ →本人確認、リアルタイム不正検知、AML/CFT →トランザクションモニタリング: ルールベースと機械学習ベースの両方をやっている、決済サービスの処理をpubsubで受け取っている →splunkに流してそこを見る 開発フロー →フローはメルカリと同じ、メルペイでは追加のルールを設けている ・Design Doc →レビューが必須、リスクを洗い出す目的 ・Dev →わりと自由 ・Test →QA、セキュリティテスト、負荷テスト →QA: 手動と自動、Postmanでやっているがメンテが大変、Goでテストケースを書いていくように移行中 →観点: マイクロサービスAPI視点でのテスト、クライアント視点でのテスト →負荷テスト: 新規機能はリリース前に負荷テストを必須にする、目標性能の見積もりとその数値の根拠 →負荷試験環境で実施 ・Production Readiness check →品質チェック ・SLO →API単位で99% latency xxx ms以内 →APIのエラー率 0.1%以下 ・Release →一般的なリリース手順と変わらない →カナリアリリースによる段階的デプロイ ・Ops →マイクロサービスの運用は開発チーム自身で行う、アラートを受けるのも開発チーム →本番環境にアクセスできるのはSREのみ(メルペイ独自) →権限の最小化、けんげんの分離 →DBの参照のみできるような取り組みもある メルカリ/メルペイの違い 安定性を求めるものが違うという考え →メルペイのほうがより高い信頼性を求められる
質疑
- 分散システムについて、Try/Confirm/Cancelとリコンサイルの両方を使っているがTry/Confirm/Cancelだけでよいのでは?
→作ったシステムに完全にバグがなければ問題ないが、自信はない、冪等性が保てているかわからないのでリコンサイルをする
→他のサービスの正しさを保証できるのか
→マスターデータとしてそれと一致するかの確認をしている、中央の決済サービスにあるデータがマスターデータとしている - マネロンなどの話、半年や1年してから発覚したときにロールバックできるのか
→不正検知があったかどうかについては把握していない
RDBのトラブルの現場を追え!
メモ
(立ち見のため一部のみメモ) DBにファイルパスを保存するのは現代だと許容されるはず →SQLアンチパターンにはNGとかいてある 無知の豪腕 →チューニングすればいい テーブル設計が悪い →テーブルをなおすしかない check成約はMySQL 8.0.16未満にはない機能 遅延制約ははじめのalter tableでしかつけられない パフォーマンスチューニングについて、ブログを紹介 https://soudai.hatenablog.com/entry/2018/05/01/204442 テーブル設計 userテーブルはidだけでinsertだけする。更新をしない →user(親)テーブルのデータは消えないので子テーブルは更新を自由にできる 子テーブルを更新するときは親テーブルは更新しない、するとデッドロックになる drop tableネタ →beginしてdrop tableしてもテーブルは消えてしまう →postgresだけはbeginでロールバックできる、MySQLはできない
質疑
- ファントムファイルを現代なら無視していいのはなぜか
→ファイルを置く場所はCDNを経由しているため。JS/CSSなど
→pdfなどのでかいものはDBに保存してもいい
→ロールバックしづらいことはないか、画像など
→画像だけは別で保存すればいい
(ここは質問者といろいろやりとりがありました) - テーブルごとに状態をもたせるとき、共通の項目が各テーブルにできてしまわないか
→userテーブルの例だとuser_detailテーブルのようにまとめたものを作ればいい - ISUCONのコツ
→DBがボトルネックになることはあまりない。n + 1とロックを注意しておけばいい
WebAuthn/FIDOのUX徹底解説 ~実サービスへの導入イメージを添えて~
メモ(≒スライドの内容)
パスワード認証の現状 FIDO →First IDentity Online →ローカル認証と公開鍵暗号の認証 →パスワードレス、追加認証に使える ーwebアプリもFIDO(FIDO2) WebAuthn →Web Authentication API →JSのAPI WebAuthnの登場人物 →webアプリ、セキュリティキー、... WebAuthnのフィッシング耐性 →耐性がある →origin(ドメイン)単位で鍵ペアを生成しているのでフィッシングサイトにはそもそもログインできない →フィッシングサイト向けのアサーションを世紀のサイトに送っても検証失敗する Android, windows10ではFIDOを使える状況が整ってきた →Authenticator, clientともに対応されてきている ユースケース →追加認証方式: パスワード認証+FIDO →メイン認証方式: パスワード認証 or FIDO 例:dropbox →platform auth, cross-platform authどちらも対応している 例:github →security keyの登録の前に名前をつける方式、よいかどうかは不明 →パスワード確認時もsecurity keyの使用ができる 例:chrome →Bluetooth経由だとandroid, PCともにBluetoothをONするだけで認証できる(ペアリング不要、caBLEというらしい) パスワードレス →パスワード認証への依存を取り除く →メール/SMS確認は認証方式ではない。コンタクト方法の確保の目的でやっている パスワード認証削除 →YJとヌーラボアカウント、どちらも削除できる →YJはメールソフトのみ残ったりするけどパスワード認証の範囲を狭くすることができる
質疑
- 昔あったようなログインレスにはできない?
→cookieのセッション管理と同じになってしまうはずなので、できない。何かユーザーのアクションが必要 - アカウントリカバリ、複数の認証方式、それ以外はないか
→セキュリティキーの中で秘密鍵の紐づけをしようとしている(そういう話がある)、がまだ実現されていない
→いまは1回無効にして再認証するしかない - 端末を買い替えたときのUIはどうなる
→無効化と新しい鍵の設定をするしかない
→スマホを壊したときはどうする
→引き出しの奥からリカバリーコードをひっぱってくるしかない - パスワードレス、FIDOが使えないときのケアはどういうものがあるか
→SMSで送信、事前に発行する、apple, googleなどHWをもっているところであればデバイス登録でもできる - 鍵交換の認証だが秘密鍵はauthenticatorの中にある、認証する側がauthenticatorの汚染を検知する仕組み(真正性)はあるか
→オプションで証明書を要求できる仕組みがある、登録処理をして戻りをはじくことはできる、その結果authenticatorがおかしいことを検知することはできる - パスワードレスの先にメールアドレス(IDとしてのメールアドレス)が不要になることはあるか
→SMSの番号だけで登録できるサービスも出てきている、リカバリのところが改善されていけばそうなることもあるかも
ソースコードを堪能せよ
メモ(≒スライドの内容)
コンパイルする前の話 コンパイルエラーでもある程度のエラーは検知できる コンパイルエラーにならないバグはたくさんある テスト、QA、監視でバグをとる 早い段階でバグは見つけたほうがいい コンパイル前にバグを見つける方法→静的解析 動的解析にはgo test -raceやgotraceなどがある 既存の静的解析ツール →いろいろある。go vetとか→Go1.10からgo testでgo vetも実行されている PRレビューで静的解析 →reviewdog 静的解析のフェーズ →字句解析、構文解析、型チェック、静的単一代入、ポインタ解析 静的解析のパッケージ →go/xxx: 標準パッケージでたくさん提供されている →x/tools/go/xxx: 準標準パッケージ import文の重複パターン →コンパイルはとおる。ただこのパターンが必要になることはない。のでなおしたほうがいい →実際にあった。protobufのパッケージをコピペしてもってきたものが別名で重複していた 型チェックで検出できるパターン →1. 不要なunexportな関数 →だいたいの場合機械的に削除しても問題ない。(reflectionやunsafepointerを使っていなければ) →2. contextを構造体に保持している →トランザクションの情報をコンテキストに保持していたパターンがあった。これはNG。更新し忘れなどが発生したりした エラー処理のミスパターン →nil以外のエラーを返すべきところでnilを返している Spannerのセッションリーク検出 →ファイルをopenしてcloseしてないのと同じやつ。deferが抜けている →検出は簡単そうに見えるが難しい →有向グラフに見立てて始端から終端の間にStop(), Do()が呼ばれていないとNG、で検出できる →Stop(), Do()のノードを取り除いたときに始端から終端までのパスがある場合はNG、とすることができる 静的解析のツール →skeltonというのが使える 採用の採点にも静的解析ツールを使ったりしている
質疑
- SSAはmutableをimmutableに書き換えるイメージ?
→2つの変数に割り当てる - false positiveへの対処はどうやっているか
→見つけてくれたほうがいいもの(クリティカルなもの)は積極的にかける、どちらでもいいものはかけない、クリティカルなものを中心にかける - ツールは組み込み以外にもある、プログラムの意味をコード上で表現するツールはあるか
→ない、skeltonはひな形を作るだけ、1個でなんでもやってくれるものではない、必要な情報を集めてくれる - プログラムの意味を表現するようなツールはあったほうがよいか
→あったほうがよい - SQLのplaceholderについてバグを検知するものはあるか
→ない、spannerについてはそういうものがあったほうがよいとは思っている
ウォレットアプリ「Kyash」の先 〜「Kyash Direct」のアーキテクチャ〜
メモ(≒スライドの内容)
Kyashアプリについての紹介 →垂直統合が特徴 Kyash Direct →企業向けSaaS製品、WebAPIで提供 KyashアプリとDirectはだいたい同じ →と思っていたけど追加するものがかなりある →Kyashへの追加よりはスクラッチ開発、モチベーションがあがる →スクラッチ開発することになった microserviceとmonolithどちらにするか →どっちもつらそう(人員的に) 課題 サービス境界 →ユースケースによってしまっている →共有したい概念んがいくつかある DBが密結合 起点のサービスが全体を把握してしまっている(密結合) →Kyashではこうなっていた Kyash Directでやった方式 pub/subで非同期で全サービスに通知をする、メッセージを受け取ったら処理する必要があれば処理する方式 DB →Event Sourcing →最終的にどうなったか →各サービスごとにDBを持ちつつEvent Storeにも投げる WebAPIをどうする問題 →Message, Eventに加えてCommand(Request), Document(Response)を追加(※Eventは全サービスにメッセージ送信するやつ、Command, DocumentはHTTPのRequest/Response相当のもの) →クライアントとMessageの間にAPI Facadeをはさむ、FacadeがHTTP request/responseを受けてMessageに変換して渡す →(いろいろあって)CQRSを導入した →(私感)めっちゃ複雑なシステムになっている気がする・・ 決済パターン →ここでもやはりTry/Confirm/Cancelの状態をもつ(Sagaパターンというらしい) Eventとは何か →Event SourcingのEventとEvent DrivenのEventは少し違っている。前者は変更があったかどうかをEventとしている トレーサビリティ →分散トレーシング →Datadog どうなったか →Goを使う、クリーンアーキテクチャの構成、しかしマイクロサービスは難しい
質疑
- サービスがたくさんあるが開発環境はローカルにあるのか
→ローカルのテストは全部ローカルで起動する、AWSもlocalというリソースがあってそれを起動する - Try/Confirmについて、Confirmできないときはどうなるか
→Tryingで残ったままになる、アラートなどで検知できるようにする、そのためにEvent Storeを使う - サービスの処理を待ち合わせて処理する場合タイムアウトはどこで責任を持つか
→処理の起点になるサービスがタイムアウトするしかない
→あとからきたものはどうするか?
→プロセッシングはタイムアウト後の戻りは無視する、NGが変えるとキャンセル処理をする
→入れ違いになることはない?
→ないはず。集約ルート単位で排他処理をしている。Tryingでロックしているものが出てくるはずなので、そうなったらEvent Storeで戻す - パフォーマンス的に問題はないか
→SNS/SQSで特に問題は出ていない
感想少し
知らないことがいろいろあって勉強になりました。
- WebAuthn/FIDO
知らなかったので勉強になりました。
WebAuthn/FIDOでもフィッシングされるのでは?と思いながら聞いていたところフィッシングに強いという説明があってなるほどと。
(origin(ドメイン)単位で鍵を生成する) - 決済システムのトランザクション管理
2つのセッションで出てきてどちらもTry/Confirm/Cancelの方式だった。これが一般的なのかな。 - Kyash Direct
だいぶ複雑というか難しいシステムになっているな〜と素朴に思いました。ちゃんとやると行き着く先はこうなるのでしょうか… - RDBのセッションで「DBは1回覚えればどこでも使える技術、知識」のようなことを言われていて確かに、そういう技術を身に着けたいですね。
明日3日目(8/31)も参加してきます。