会員登録時の画像アップロード処理を改善した
概要
現在toBtoC向けの予約システムを開発しています。
- toBとは「予約システムを導入しているサロン企業様」
- toCとは「サロン企業様にいらっしゃるお客様」
です。
予約システム利用前に、利用者は必ずこのページに遷移して会員登録を行います。
会員登録フォームに 「スマホで撮影した身分証明書」 を添付して送信してきます
イメージ図
想定より検討すべき点が多かったので、今回記事にまとめました。
もっと改善点あったらコメントくださると嬉しいです!🙏
前提
- RailsサーバーでHTMLを表示するオールドスタイル on Heroku
- javascriptで直接画像をPOSTするパターンではない
- 開発者は基本的に私1人のみ。
- 会員数は3万人
- 新規会員登録は平均20人/日
対象読者
- 基本的な機能開発に慣れてきた人
- 設計についていろいろ考えたい人
いいね!してね
この記事の事例は必要に応じて今後追記していく予定です!
「新しい事例が知りたい」「他の事例も知りたい」と思った人は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!
それでは以下が本編です。
結論
MPAサーバーの場合(今回)
フロントがやること
- フォームにセットした画像のバリデーション(メタ情報が画像か? 上限サイズ内か?)
- セットした画像の圧縮処理
バックエンドがやること
- リクエストパラメータ内の画像のバリデーション(メタ情報が画像か? 上限サイズ内か?)
- 外部ストレージサービスへ画像をPOSTする(DB処理にtransactionを貼る場合は、最後に処理する)
フロント、バックエンドが別の場合
この記事が一番良いと思いました!
説明すること
- 仕様調査
- 検討
- 改善
調査
仕様: シーケンス図
(3)LINEログイン認証後、利用者(Mobile Client)が会員登録ページに遷移します。
(5)利用者は、手持ちのスマホで会員登録フォーム用の身分証明書を撮影します。スマホの画質が良すぎて画像容量が約6MB前後になります。
(7)~(15)サーバー側で
- バリデーション
- 画像ファイル容量の圧縮
- 会員レコード生成
- 画像ファイルをストレージにPOST
をしていました。
現状の問題点
で、Response Timeが5秒~30秒もかかっていました。
フロント(4G回線で6MB程度の画像ファイルをPOST) これが原因では🤔
↓
サーバー(画像容量圧縮 + 300KB程度の画像ファイルをPOST)
↓
GCS
検討
を再度読む。
今回はオールドスタイルRails(MPA)なので、この文脈で検討していきます。
1案 フロントから直接ストレージにPOSTする
フロントから非同期で直接ストレージ(仮バケット)に配置する案。
- バックエンドが事前に生成した署名付きURLを使う。
楽なので、あり。 署名付きURLの生成回数に上限はないっぽい。 - フロントが直接POSTするストレージは仮バケット。
バケット移動の実装がだるい
事前にLINE認証処理しているため、ファイルのデータ検証までしなくていい気がする - フォーム処理完了後、ワーカーかバッチでストレージ(仮→本バケット)に移動させる
バケット移動の実装がだるい。ワーカーかバッチの処理を増やしたくない。 - POST処理に失敗して離脱すると仮バケット内にファイルが滞留する。
定期的に削除する(削除しなくても直ちに問題にならない) あり。
→面倒なので「一旦なし」と判断。
2案 フロントで画像を圧縮する
サーバー側の処理時間が減るので、あり
※ただし、この程度ならライブラリ入れないで実装する。
検討結果
コスパ重視で2案を採用しました(2案は1案と共存できますし)
改善
実装
(8)の画像圧縮の処理をフロント側で行うようにしました。
結果
平均10秒以下に収まったように見える🚀
※昨日リリースしたので、一旦経過観察中。
最終的にResponseTimeが3秒以内になると期待していましたが、5秒程度が多い結果になりました。
どこがボトルネックになっているか詳細は改めて調査します。
まとめ
Response Timeの閾値10s以内に設定していたら、頻繁にアラートが飛んできてました。
機能開発優先で、場当たり的な実装をしてきてしまったツケでしょうか。
最近、外資系転職対策教材でシステムデザインパターンを見るようになりました。
(頻出する)API設計のベストプラクティスをまずは頭に入れて、個々の実装で臨機応変に対応していきたいですね。
この記事の事例は必要に応じて今後追記していく予定です!
「新しい事例が知りたい」「他の事例も知りたい」と思った人は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!
Discussion