Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Qiitaアーキテクチャの15年史:モノリスRailsから巨大化するサービスの技術負債をどう解...
Search
Tomoya Chiba
November 19, 2025
1
200
Qiitaアーキテクチャの15年史:モノリスRailsから巨大化するサービスの技術負債をどう解消するか
アーキテクチャ Conference 2025 (
https://architecture-con.findy-tools.io/2025
) での発表資料です。
Tomoya Chiba
November 19, 2025
Tweet
Share
More Decks by Tomoya Chiba
See All by Tomoya Chiba
スポンサーブース用の ruby.wasm くじを vibe coding した話
tomoasleep
0
120
東京Ruby会議12ヘルパー楽しかった✌
tomoasleep
0
140
rbs-inline 生成してみた
tomoasleep
1
330
LiveShare で森羅万象を共同編集する(?)
tomoasleep
1
730
GitHub Actions による RSpec の時間を半分以上短縮した話
tomoasleep
2
1.5k
ts-morph と ast-grep でたくさんの TypeScript コードを書き換えた話
tomoasleep
4
4k
render 出来るオブジェクトの作り方
tomoasleep
0
250
Rails アプリを10年以上継続していくためのフロントエンドの底上げ
tomoasleep
3
1k
Rails のブラウザテストを Playwright で動かすようにしたらデバッグが簡単になって捗った
tomoasleep
4
3.1k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Unsuck your backbone
ammeep
671
58k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Faster Mobile Websites
deanohume
310
31k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
Speed Design
sergeychernyshev
32
1.2k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
11
930
Git: the NoSQL Database
bkeepers
PRO
432
66k
Statistics for Hackers
jakevdp
799
220k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8k
Practical Orchestrator
shlominoach
190
11k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Transcript
Tomoya Chiba (Qiita,GitHub: @tomoasleep X: @nemunemu3desu) Architecture Conference 2025 #
Qiita アーキテクチャの15 年史:モノリスRails か ら巨大化するサービスの技術負債をどう解消するか 1
@tomoasleep (Tomoya Chiba) Qiita 株式会社のリードエンジニアです。 学生アルバイト、正社員、退職、出戻りを経て、10 年くらい Qiita に関わっています。 ##
p self 2
### Qiita から来ました 3
### Qiita Team 4
### Qiita のアーキテクチャ図 ( 雑) 5
### Qiita のアーキテクチャ図 ( 雑) 5
Ruby on Rails を中心としたモノリシックアーキテクチャ 複数サービス (Qiita, Qiita Team) を同一コードベースで運用 フロントエンドでは近年は
React 中心 インフラ AWS ECS 上で稼働 MySQL, Redis, Elasticsearch 等を利用 ### Qiita が採用しているアプリケーション構成 6
### Qiita はもうすぐ 15 周年 7
### Qiita も大きくなった 8
### Hello World to IPO (Qiita は IPO してないが) 9
長年やってるとサービスは複雑化する ユーザー数の増加、様々な改善 事業の拡大 AI 時代への対応!! 複雑化するサービスの改善も色々やってきた 正直しくじったこともある Qiita の事例を通じて、 「改善をどうやっていくか」を話したい
### 今日の話: 複雑化する Rails の改善の Try を共有 10
15 年の事例を全部 30 分の発表に持ってくるのは無理だった ブースや Ask the Speaker で色々話せます! Qiita
の気になるところ Rails フロントエンドの変遷 GraphQL Ruby 使ってる話 Qiita の ECS への移管 ...etc ### 11
よくあげられる改善手法をどっちも試した Service 層の導入 モジュラーモノリスの導入 ## Qiita で試みた、アーキテクチャレベルの改善事例 12
Service 層の導入 → 失敗 モジュラーモノリスの導入 → ( 今のところは) 成功 ###
改善の結果 13
Service 層の導入 → 失敗 モジュラーモノリスの導入 → ( 今のところは) 成功 この結果の違いは、設計手法の良し悪しよりは導入方法の違い
によるもの ### なぜ、結果に違いが出た? 14
## 過去の Qiita のアーキテクチャ改善事例の紹介 15
### 事例1. Service 層の導入の失敗 16
これ (Rails の MVC) を #### Service 層とは 17
こう (Controller と Model の間に追加する) #### Service 層とは 17
操作を表現するレイヤー、クラス DDD や PoEAA あたりで出てくる Rails においてはいわゆる Fat Model が辛くなってきた時に、新たなレイヤーとし
て導入を検討することが多い #### Service 層とは何か 18
Rails の基本構成は Model, View, Controller サービスの成長とともに Rails の Model は色々出来、肥大化したり辛くなりがち
Model から操作を Service に抽出し、 Controller と Model の中間に置く #### Fat Model が辛くなるとは 19
class Article < ApplicationRecord # Validation validates :body, presence: true,
if: :update_by_post? # Callback after_save :send_mention_mail, if: :update_by_post? end 特定のケースだけ、値をチェックしたい or 通知を送りたい、となると複雑化 #### ( 極端な) Model のアンチパターン 20
class PostArticleService def call(**attributes) # (Post 時の Validation 処理 が入る)
fail ArgumentError, "body is required" if attributes[:body].blank? # Model の操作 article.update!(**attributes) # (Post 時の Callback 処理 が入る) send_mention_mail(article) end end Model の持っている責務を Service に移す #### Service 層のコードのイメージ 21
大型の新機能開発で、今後の Fat Model 化を防ぐために Service 層を導入してみ ることに Controller から Model
を直接使わず、 Service 経由にする 結果: 開発で「迷い」が生じて遅くなってしまい、導入中止 「ちょうどよい Service 層」を作るのにチームで迷ってしまった #### ということで Qiita でも導入してみる 22
Service "" 層"" として強制するとデメリットも有る Model が薄くなりすぎて、重複コードが増える可能性がある ( ドメインモデル貧 血症) Service
側の分、通常よりも書くコードが増える 元々 MVC で簡潔に書けていたものが、冗長に ( 例: CreateXXXService) #### Service 層は万能ではない 23
「ちょうどよい Service 層」をチームで作れず、コードがぶれた Model と Service のどっちに書くべき?の基準を作れなかった 社内にノウハウが無いため「ちょうどよい Service 層」を皆で模索してしまっ
た 新機能では「Fat Model 問題」はまだ起きてないので、基準が作りにくい 新機能の設計で悩むべき時間を奪ってしまうことに → 最終的に、 「サービス層は無い方が良い」となり中止 #### メンバー間の活用認識が揃わなかった 24
投入する範囲を広げすぎてしまった ( すべての操作に導入しようとした) 冗長なケースでデメリットが目立つ 投入すべきタイミングを見誤った ノウハウが溜まっていない状態で、チームで実践投入してしまった デメリットが目立つことに Fat Model 問題が顕在化していない段階で導入を試みた
導入のメリットが見えにくい #### ふりかえり 25
### 事例2. モジュラーモノリス設計の導入の成功 26
Rails アプリを小さな Rails アプリに分割するイメージ #### Rails でのモジュラーモノリスとは 27
出典: 「モノリスからマイクロサービスへ」1.2.1 単一プロセスのモノリス モノリスと同じく単一アプリケーションだが、モジュールに分割されている アプリケーション内に境界を設け、モジュールとして分割 ( マイクロサービス的) アプリケーションは同一のランタイムで動作する ( モノリス的)
#### モジュラーモノリスとは 28
これらのライブラリで「モジュール」 を実現 packs-rails: 別ディレクトリ (packs/xxx) に移動 packwerk: モジュール間のアクセ スを制限 ####
Rails での「モジュール」の実 現 ( 詳しく知りたい人向け) 29
「Qiita のイベント用実装をモジュール化して分離すること」を目的として導入 数回の試行ステップを経て、小規模開発で実践投入 結果: 混乱なく導入に成功、目的も達成 #### Qiita におけるモジュラーモノリス導入 30
Service 層導入の失敗を避けるように動いたから ゴールや解決する問題を具体的に定めた 試行リファクタリングを行った 「迷うポイント」を、少人数のうちに発見できるように動いた #### モジュラーモノリス導入はなんでうまくいっているか? 31
こう (Qiita の機能を細かくモジュールに分ける) ではなく #### Qiita でのモジュラーモノリス導入後のイメージ 32
こう ( イベントを切り離す) #### モジュラーモノリス導入がゴールではなく、問題解決がゴール 33
#### Qiita にはめっちゃいろんなイベントがある 34
#### Qiita にはめっちゃいろんなイベントがある 35
#### Qiita にはめっちゃいろんなイベントがある 36
#### Qiita にはめっちゃいろんなイベントがある 37
こうしたイベントもモノリスで開発していた が、だんだん辛さが目立つようになってきた 実装があちこちに散らばり、把握が難しい 短期集中で開発したいがやりにくい イベント用コードとそれ以外のコードが結合している これらの辛さを解消したい #### イベントが増えて辛くなってきた 38
変更したコードをリポジトリにチェックインせず破棄することを前提として、 様々なリファクタリングを行い、変更対象のコードを理解する手法 「レガシーコード改善ガイド」より 導入前に、一旦手元で「思いつくモジュール分割」を一通り試す この試行で「分割で悩みそうな箇所」 「ハマりどころ」を把握 やってみた感触 イベント関連は比較的すんなり切れて見通しが良くなりそう Qiita のコア機能はどう切るかで「迷い」が発生しそう
→ ( まずは) 「イベント用の実装を分離すること」にフォーカス #### 試行リファクタリングで、どう導入するべきか検討 39
40
チーム開発にいきなり実践投入せず、小さく試しながらノウハウを蓄積していった 自分が迷う部分と、チームメンバーが迷う部分は別 小規模な開発プロジェクトで試験導入 他のメンバーが迷う部分を把握 & 対応方法をドキュメント化 #### 小規模開発でノウハウを貯める 41
イベント実装の切り離しは混乱なく完了 イベント用コードがまとまり、見通しが良い状態に 小規模なうちに指針も明確になり、混乱も生まれず #### スムーズな導入に成功 42
イベント外でも、モジュラーモノリスが活きる部分を少しずつ試している 外側から少しずつ切り離す感じ 社内ライブラリ 独立性が高いページ ( 管理画面など) #### 余談: モジュラーモノリス導入後の現在 43
## アーキテクチャ移行事例からの学びをふりかえる 44
結果の違いは何が生んだ? 45
Service 層、モジュラーモノリス、どちらが良い悪いではない Service 層: 操作 (Service) のクラス化という発想自体は、Fat Model を整理する上で 有用
冗長化、 Model との棲み分け モジュラーモノリス: 単位それぞれで見通しが良くなる、複数チームなら独立して開発しやすく 分割しすぎると、何をどこに置くべきかで無駄に悩んでしまう オーバーに適用すると、考えることが増えてしまう、という点では共通 ### 違いは手法の良し悪しではない 46
Service 層 vs モジュラーモノリス すべての操作に導入 vs 適用する箇所を絞って導入 複数人開発にいきなり実 践 vs
少人数でノウハウを貯めてから実 践 ゴールを明確にして適用する場所を絞ったか、 「迷う部分」を少人数のうちに減ら せたか、が差 #### 適用範囲と導入方法の違い 47
逆に考えると 48
簡潔に書けるような仕組みが整っているから ActiveRecord, ActionView, ...etc などの強力なライブラリ群 ルールの存在で考えること少なく開発出来るから ( レールに乗れるから) MVC 設定より規約
良いデフォルト設定 (Omakase) ...etc コミュニティのナレッジを借りれる #### そもそも Rails の開発はなぜ早いか? 49
Rails のレールでやれるところは Rails のレールでやる 外れるときは、代わりのレールを敷くつもりで動く ( それぞれが迷わないようにす る) どう書くか、どう考えているか共通認識や仕組みを整える 十分に試行する
コミュニティの力を借りてうまく外れる #### 教訓: Rails のレールを外れるなら、 Rails の強い部分から学ぶのが重要 50
フレームワークの効力としてこれが実は大きい すでに似たような問題に直面している人がいる 先人の知恵を借りる Qiita の改善でも非常にお世話になった #### 余談: コミュニティの力は大きい 51
ということで 52
「次の誰かを助けられる場」としてあり続けられるように頑張ります ### Qiita もコミュニティとして引き続き頑張ります 53
最後に宣伝 54
( アーキテクチャカンファレンスの学びも Qiita に残していってくれると嬉しいで す!!) ### Advent Calendar 2025 受付中です!
55
Qiita に関して色々話せます! ノベルティも配ってます! ### ブースやってます! 56