Closed maeda-m closed 1 year ago
マイクロサービスよりもモノリシックモノリスを選択する。
それはマイクロサービスはコンテキストや Frontend と Backend で独立してリリースする目的であるため、 ひとりで開発するのであればモノリシックモノリスがよいと判断しました。
技術名 | どんな状況の | どんな問題・課題を | どのようにして解決しようとする技術 |
---|---|---|---|
モノリシックモノリス | PoSA本にヒントがあるかと思いざっと読んだがよくわからなかった | - | アプリケーションを1つのコード ベースで構築する |
マイクロサービス | 大きくなりすぎてスケーリングが困難なモノリシックアプリケーション | 1つの機能に小さな変更を加えるために、全体をコンパイルしてテストする必要がある 機能を更新することで無関係な機能にバグが入るリスクがある |
データベースの分割やシステムのコンテキストで分割することでコード管理、認知コスト、デプロイを容易にする |
MySQL よりも PostgreSQL を選択する。
今回のような小規模アプリケーションであれば性能的な差や用途による選定は難しいため、次の2点で判断した。
Passenger よりも Puma を選択する。 それは少ないメモリのサーバーで、マルチスレッドにより I/O 待ちの応答時間が短縮されるからだ。
Puma 公式サイト を見ると圧倒的にパフォーマンスがいいことがわかります。
また Heroku が推奨するプロセス数とスレッド設定 を見ると Heroku - Standard-2X Dyno では 2
プロセス、 5
スレッド となりました。
Passenger の OSS 版では 1プロセスあたりの最大使用スレッド数の計算式 が用意されているため、Heroku - Standard-2X Dynoのスペックで計算しました。
計算式:
((1024 * 2 * 0.75) - (2 * RAM_PER_PROCESS * 0.9)) / (RAM_PER_PROCESS / 10) / 2
RAM_PER_PROCESS を 100
とすると計算結果は 67.8
となりました。
上記の計算結果から、もしスレッド数が多くなりすぎてスワップが頻発すると、レスポンスの遅延が発生しそうです。
Apache よりも Nginx を選択する。
今回のような小規模アプリケーションであれば性能的な差(DDos対策なども含める)や用途による選定は難しいため、人気度で判断した。
比較サイト | Nginx | Apache |
---|---|---|
GitHub | スター数 18.3k | スター数 3.2k |
Docker Hub | スター数 10K+ | スター数 4.4K |
2022 Ruby on Rails Community Survey Results | 人気度 1位 | 人気度 3位 |
Hotwire で十分と判断した。 それは、今回のような小規模アプリケーションでは反応性が必要なところがあまりためだ。
必要であればバニラJS(ES2022 の構文)または Stimulus で実装するため、TypeScript などのトランスコンパイルは不要(もし大規模になるのであれば jsbundling-rails + esbuild で考え直す)。バンドリングは importmap で代替 する。
なおミニファイルや使われていないコードの自動削除については極力しておきたいが、実際にブラウザの読み込みを計測してから考える。
方針としては次のとおり。
data: { turbo_frame: "_top" }
でTurbo Drive の挙動にするTurbo.renderStreamMessage(streamActionHTML)
をすると Turbo Streams でアクションを実行するformaction
や form
属性によって振り分けるまた CSS は Tailwind を暫定導入とします。デザインの都合で差し替えるかもしれません。
OpenId Connect で Google アカウントのID、メールアドレスを取得できた。 ボタンについては下図のようにHTMLの内容によってテキストを変えられるようだ。
あとは取得したアカウントIDを bcrypt でハッシュ化し、DBに保存すればよさそう。
バックエンドはRuby 、 REST 前提とします。
Rails かそれ以外か
テスティングフレームワークは RSpec か Minitest か
議題に書いていた理由(以下、抜粋)により RSpec を利用する。
基本的に受け入れテストを多めにして、単体レベルのパターン網羅が必要な場合は単体テストを網羅的に書く方針としたい。
あわせて https://github.com/jnicklas/turnip と https://github.com/microsoft/playwright 1 、 https://github.com/danmayer/coverband を導入する。
また必要に応じて次の Gem も導入する。
書式「〇〇よりも△△△を選択する、それは(どんな状況の問題・課題を解決しようとした技術)だからだ。」で結論をコメントする。
https://bootcamp.fjord.jp/practices/226
参考情報
https://speakerdeck.com/toricls/you-wont-be-in-the-team-forever?slide=24
以下、検討項目。
システムアーキテクチャ
モノリシックモノリスかマイクロサービスか?
開発言語・フレームワーク
バックエンド
バックエンドはRubyを前提とします。また REST 前提であるため GraphQL は使用しません。
Rails かそれ以外か
永続化レイヤーをどうしたいか?で判断する。
テストをどうしたいか?
テスティングフレームワークの RSpec か Minitest を選ぶ。
基本的に受け入れテストを多めにして、単体レベルのパターン網羅が必要な場合は単体テストを網羅的に書く方針としたい。 というのも、プロジェクトではなく、プロダクトであるため、変更を受け入れやすくするため、E2Eでテストしておけば最低限の品質は担保できるだろうという判断です(変更を受けれにくくする単体テストは書かない)。
また受け入れテストを自然言語で表現し、裏ではテスティングフレームワークで頑張る方針にしたいが、E2E で Turnip などを選択している場合は RSpec 一択になる。
本体のコードベースをより少ないコードにするには?
必要そうな機能を Gem で実現できるかを検討する。‘もしなかったら開発時に
lib
配下に実装してから Gem に分離する。フロントエンド
バニラJSかライブラリか
Hotwire で十分かもしれない。
認証
Googleアカウントの識別子を使用したい。
API とサービス – Google Cloud コンソール
から OAuth の設定をして検証用のコードで試す。アプリケーションサーバー
本番環境をマネージドサービスでなく自前で用意する場合は検討が必要。 Puma か Passenger かを選ぶ。
ウェブサーバー
本番環境をマネージドサービスでなく自前で用意する場合は検討が必要。
Nginx か Apache かを選ぶ。
データベースサーバー
PostgreSQL か MySQL かを選ぶ。もし永続化としてふさわしければ sessionStorage も検討する。 なお 私の古い知識としては MySQL は order by で index が効かないパターンがある認識です。