はじめに
2024年10月25, 26日に有明で行われたKaigi on Rails 2024に、参加してきました!! 今回はKaigi on Rails初参加かつ最近Railsの世界に飛び込んだメンバーが気になったセッションをレポートしていきます!
レポーター
otaka(@oh_minisera) 新卒は病院で理学療法士として従事。2社目からエンジニアに転職しシステム開発会社、DMM.comを経て2024年5月にスマートバンクにJOIN。 今までPHP、Server-Side Kotlinを使用。スマートバンクからRuby on Railsを始める。
kurisu(@ryomak_13) 2024年3月にスマートバンクに入社。前職まではGo/Javaと静的型付け言語での開発。 スマートバンクに入社してからRuby on Railsを始める。
Day 1
Railsの仕組みを理解してモデルを上手に育てる - モデルを見つける、モデルを分割する良いタイミング
登壇者は「Railsの練習帳」や「パーフェクトRuby on Rails」の著者である @igaiga555 さんです。モデルの見つけ方から、複雑化を避けつつ役割を分割するタイミング、実装手法に至るまで、具体的なケーススタディを交えた解説が行われました。
セッションは前編「モデルの見つけ方」、後編「モデルを分割する良いタイミング」に分けて解説されました。
モデルの見つけ方では、アプリケーションの業務上の単位をイベント型モデルとして捉えることが重要とされていました。これにより責任範囲を明確にしつつ、他のモデルから独立させやすくできます。また複雑化を避けるため、不要なService層を追加せずにイベント型モデルやPOROを活用する方法が推奨されていました。
クリーンアーキテクチャがメジャーな現場から、Railsの世界に飛び込んだ身からすると「なぜService層を追加してビジネスロジックを分離させないのだろう」と疑問に思っていましたが、それに対する解が出ました。一方で、もし密結合によるデメリットで辛くなりそうな時はイベント型モデルの導入も検討していきたいです。
モデルの分割のやり方は、いわゆるFatモデルの判断基準と具体的な分割方法をフォームオブジェクトの実装を例に紹介されていました。分割するタイミングの一つは「バリデーションを条件分岐したくなった時」。その際にフォーム用とDB用それぞれの仕事に分離させることを推奨されていました。
話を聞きながら「我々のRailsアプリケーションは綺麗に分離されているなあ」と改め初期設計をされた方へのありがたみを感じました。これからスマートバンクは更に拡大します。それに伴いモデルを丁寧に育てていきたいと強く思いました!
登壇資料 speakerdeck.com
デプロイを任されたので、教わった通りにデプロイしたら障害になった件 〜俺のやらかしを越えてゆけ〜
登壇者は株式会社株式会社Techouseの @12u3i_tomo さんです。過去のデプロイで経験した障害を振り返りながら得た学びを解説されていました。
最初の障害は、DBマイグレーションが反映されてから古いコンテナが停止するまでの間、古いコンテナのDBコネクションにPreparedStatementが残ってしまい、エラーが発生したケースです。この問題を回避するため、config.active_record.enumerate_columns_in_select_statements
をtrue
に設定することでワイルドカードクエリを避ける対応したとのことです。
次に紹介されたSidekiqのジョブ停止問題は、デプロイ時にSidekiqがジョブを実行中であるにも関わらず、全てのジョブが停止してしまったという問題です。原因は、SidekiqにSIGTERMシグナルが届かず、強制的にSIGKILLシグナルで停止されたことでした。Sidekiqをエントリプロセスとして起動することで、シグナルを適切に受け渡しする対応をしたとのことです。
障害発生時の影響範囲、原因調査がとても丁寧でした。Rails内部の挙動まで深掘りして理解を深める行動もさることながら、問題解決に向けて全社的な対応に持っていく巻き込み力の重要性を改めて感じました。
また、懇親会で @12u3i_tomo さんとお話する機会があり、かなりセッションが盛り上がっていたという話をしたところ、昨年の mitaniさんのKaigi on Railsの登壇資料を参考にしたというエピソードを聞きました。発信が誰かの役に立っていることを実感し、自分自身も意識して発信をしていきたいと思いました。
登壇資料 speakerdeck.com
Capybara+生成AIでどこまで本当に自然言語のテストを書けるか?
登壇者は @yi01imagination さんで、生成AIを活用して自然言語でテストを書き、それをCapybaraで実行するという実験的なアプローチのお話でした。
人間が手動でテストする時の挙動と機械とのギャップとして、アクションを実行した後のフィードバックがないという観点に着目されていました。このギャップを埋めるために、ブラウザ画面の画像を入力情報として渡し、自然言語で書かれた期待通りのテストができているかをチェックするアプローチを試されていました。従来のテストコード作成の自動化に加え、生成AIがスクリーンショットなどの情報を受けて、テストコードを修正していくという点がとても面白いなと感じました。
セッション中、デモも行われ、ログインを突破した時は歓声が上がっていました。今後のテスト手法としての可能性をとても感じる内容でした。今回のCapybaraのドライバーはGitHubに公開されておりました。生成AIのプロンプトやセッションでお話しされていたinput_toolとても参考になります。
また、生成AIの活用だけでなく、現状の課題をモデル化し、人間とシステムの間にあるギャップを生成AIがどう埋められるかという思考の整理が個人的にはとても刺さりました。
登壇資料 speakerdeck.com
Day 2
推し活のハイトラフィックに立ち向かうRailsとアーキテクチャ
登壇者は株式会社TwoGateの @falcon_8823 さんです。Caravanというイベント物販に特化したアプリの先着販売の事例をもとに、「在庫確保」と「決済」のパフォーマンス向上についての工夫を詳しく解説されていました。Rails上での8000rpsや、決済660rpsという非常にハイトラフィックな環境での対応事例であり、リアルタイムでの高負荷に対応する方法がとても勉強になりました。
在庫確保の工夫では、商品に対して在庫数を直接持たせるDB設計ではなく、1レコード1在庫という構造にしているとのことです。数百RPSのアクセス下で在庫確保をスムーズに行うため、 FOR UPDATE SKIP LOCKED
を利用し、行ロックが発生している在庫レコードをスキップしながら取得することで、デッドロックを回避。これにより200万在庫もの商品も問題なく捌けたとのことでした。
決済は、PCI DSS観点で外部のペイメントプロバイダを利用しているとのことでした。APIレートリミットには制限があり、オーソリ→在庫確保→売上確定といった処理フローの途中で、レートリミットに達するとエラーが発生してしまう問題もあったとのことです。 キューでの非同期対応等も検討されたとのことですが、限界に対して正しく向き合うという観点で、処理が限界に達した場合にリクエストを受け付けないレートリミットを導入する判断をされたとのことでした。
ハイトラフィックを捌くためには、Rails単体ではなく、Web全体を通して改善していく「総合格闘技のようなもの」とおっしゃっていたのが印象的でした。 ハイトラフィックに対応する設計について知る機会は中々なかったのでかなり勉強になったのと、Rails単体での最適化にとどまらず、Web全体を見据えた設計の重要性を改めて感じました。
登壇資料 speakerdeck.com
約9000個の自動テストの時間を50分から10分に短縮、偽陽性率(Flakyテスト)を1%以下に抑えるまでの道のり
登壇者はSHE株式会社の @hatsu_38 さんです。CIにかかる時間が50分、FlakyテストによってCIが失敗する確率が15%だったところを、CIの時間を10分、失敗率は1%と大きく改善した際にやったことを具体的に解説されていました。 明日から使えるテストの速度向上と信頼性確保を両立させる手法がとても勉強になりました!
テスト時間短縮には、キャッシュの活用と並列実行が鍵とのことでした。
キャッシュの活用では、test-prof のbefore_all
やlet_it_be
でテストデータの複数回に渡る作成を抑えていました。また、テストの並列処理には parallel_tests を導入し、複数のCPUコアを使ってRSpecを高速化する方法を紹介されました。そしてparallel_testsを最大限に活用するためにファイルを分割することを推奨されていました。
Flakyテストの抑制には、Allure Report を使ってテスト結果のレポーティングを見やすくする方法を紹介されていました。スマートバンクではCIはGitHub Actionsを使っており、テストが失敗した際の原因が見にくく個人的に辛さを感じていました。これを導入することにより、テスト結果が見やすくなる他、カバレッジ数や過去のテスト履歴も綺麗にビジュアライズされるので自分にかなり刺さりました。
発表後、登壇者の @hatsu_38 さんにどのくらいの期間で改善を行ったのか聞いたところ、サイドプロジェクトで半年ほど取り組んでいたそうです。このような運用の改善系のタスクは積まれがちですが真摯に取り組まれた行動に拍手を送りたいです!
登壇資料 speakerdeck.com
Identifying User Identity
登壇者は「Rails 3レシピブック(共著)」「はじめる! Cucumber」の著者である @moro さんです。webアプリケーションとは切っても切り離せない”User”モデルの設計について解説されました。
「ユーザー」と一口に言ってもサービスの領域ごとに様々な呼び名があり、即断で”usersテーブル”を作るのはどうなんだろうという問題提起から始まりました。そして架空のシステムを題材にしながら”User”モデルの設計について紹介されました。
moro さん曰くシステムにおけるユーザーは「identifyしたい単位」であります。そのためusersテーブルには主キーid(とcreated_at)のみがあれば良いと提言されました。確かにusersテーブルには名前やメアド、電話番号などを入れたくなりますが利用するシーンは少ないです。また認証情報を別テーブルに分離することで分析環境との連携時に隠蔽できるなど恩恵が多いなと感じました。
また、この設計は認証認可の面でも有利と解説されました。初期にIDとパスワードの認証方法があり、サービスを育てていく過程で新たな認証プロバイダを利用したいとなった時に追加や切り替えが容易になることもお勧めされていました。
ユーザーを「identifyしたい単位」と捉え、サービスの成長と共にカスタマイズできるような設計が重要だなと感じました。スマートバンクのusersテーブルもこの発表で説明された設計と近いものになっています。実際に開発をしながら恩恵を感じており「うん、うん」と頷きながら発表を聞いておりました。
登壇資料 speakerdeck.com
いかがだったでしょうか!
各セッションの熱量をより伝えることができていれば幸いです!🔥
皆さんKaigi on Rails 2024 お疲れ様でした!!
セッションから多くの学びを得た上で、その場で他のエンジニアと意見交換ができたため、さらに理解が深まりました!また業務レイヤーに近い知見を沢山得られたので、明日からのプロダクト開発に活かしていきます。
スマートバンクではRuby on Railsを中心にプロダクトを急成長させるフェーズです。 一緒にプロダクトを育てたい方、Rubyコミュニティを盛り上げたい方、絶賛募集中です!!
smartbank.co.jp smartbank.co.jp