Upgrade to Pro — share decks privately, control downloads, hide ads and more …

クックパッドの巨大 Rails アプリケーションの改善

hogelog
September 12, 2018

クックパッドの巨大 Rails アプリケーションの改善

hogelog

September 12, 2018
Tweet

More Decks by hogelog

Other Decks in Technology

Transcript

  1. hogelog (小室 直) • 2013/8 クックパッド株式会社 入社 ◦ レシピ投稿関連の開発等(Web, Android)

    ◦ 会員事業関連、OEM 向け API 開発等 (Web, Android) ◦ 技術部開発基盤(いろいろ)
  2. cookpad_all とは • cookpad.com を支える複数の Rails アプリと共有ロジック をまとめた shared gem

    を含むリポジトリ • cookpad_all 内の各アプリはほとんど共有 DB
  3. 一昔前のクックパッドの開発風景 • 大多数の社内エンジニアが cookpad_all で開発する状況 • 開発基盤、インフラのリソースも cookpad_all に集中 ◦

    強いモノリシック Rails アプリの時代 ◦ The Recipe for the World's Largest Rails Monolith by @a_matsuda https://speakerdeck.com/a_matsuda/the-recipe-for-the-worlds-largest-rails-monolith
  4. 2016 年頃のクックパッドの開発風景 • Microservices が進み cookpad_all 以外の開発が増える • cookpad_all は巨大だし辛い

    • cookpad_all は基盤からレガシーな部分が多く整備コストも 高い ◦ Microservices 基盤は整っていく ◦ クックパッドにおける最近のMicroservices事例 by @adorechic https://techlife.cookpad.com/entry/2016/03/16/100043
  5. 2017 年、お台場プロジェクト発足 • @aamine により立ち上げられた cookpad_all 改善プロ ジェクト • 裏の目標は「開発基盤」というチームの解散

    ◦ cookpad_all はもうサービス開発チームが高い意識による片手間程度でメ ンテナンスできる規模ではない ◦ cookpad_all を徹底的に改善し、普通の開発チームでメンテナンスできる 状態にする
  6. 開発メトリクスの定点観測 • コード量、起動時間などの開発メトリクスを InfluxDB に記 録、Grafana のダッシュボードで定点観測 ◦ 大きな Rails

    アプリケーションをなんとかしよう。まずは計測と可視化からは じめよう。 by @hogelog https://techlife.cookpad.com/entry/2018/06/08/080000
  7. 2017-07-01 時点の stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC

    | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 55217 | 44464 | 619 | 4505 | 7 | 7 | | Helpers | 16853 | 13810 | 21 | 1582 | 75 | 6 | | Models | 95824 | 75336 | 1892 | 8854 | 4 | 6 | | Mailers | 2011 | 1612 | 45 | 199 | 4 | 6 | | Workers | 841 | 712 | 25 | 40 | 1 | 15 | | Chanko units | 8656 | 7160 | 2 | 169 | 84 | 40 | | Libraries | 50869 | 42003 | 660 | 3779 | 5 | 9 | | Feature specs | 58694 | 47269 | 0 | 189 | 0 | 248 | | Request specs | 56536 | 48938 | 0 | 24 | 0 | 2037 | | Routing specs | 544 | 437 | 0 | 0 | 0 | 0 | | Controller specs | 63233 | 52246 | 6 | 123 | 20 | 422 | | Helper specs | 5318 | 4389 | 1 | 10 | 10 | 436 | | Model specs | 91372 | 75504 | 5 | 85 | 17 | 886 | | Worker specs | 1150 | 954 | 0 | 1 | 0 | 952 | | Chanko unit specs | 7845 | 6293 | 0 | 8 | 0 | 784 | | Library specs | 26156 | 21905 | 23 | 123 | 5 | 176 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 541119 | 443032 | 3299 | 19691 | 5 | 20 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 185097 Test LOC: 257935 Code to Test Ratio: 1:1.4
  8. 2018-09-12 時点の stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC

    | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 32080 | 25883 | 305 | 2690 | 8 | 7 | | Helpers | 13212 | 10739 | 17 | 1214 | 71 | 6 | | Models | 73703 | 58028 | 1282 | 6540 | 5 | 6 | | Mailers | 1663 | 1336 | 38 | 165 | 4 | 6 | | Workers | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko units | 6154 | 5142 | 2 | 147 | 73 | 32 | | Libraries | 33604 | 28014 | 373 | 2449 | 6 | 9 | | Feature specs | 43505 | 34908 | 0 | 176 | 0 | 196 | | Request specs | 809 | 637 | 0 | 0 | 0 | 0 | | Routing specs | 406 | 328 | 0 | 0 | 0 | 0 | | Controller specs | 48137 | 39729 | 2 | 76 | 38 | 520 | | Helper specs | 4151 | 3430 | 0 | 9 | 0 | 379 | | Model specs | 63788 | 52339 | 2 | 52 | 26 | 1004 | | Worker specs | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko unit specs | 2961 | 2359 | 0 | 1 | 0 | 2357 | | Library specs | 16383 | 13588 | 17 | 86 | 5 | 156 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 340556 | 276460 | 2038 | 13605 | 6 | 18 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 129142 Test LOC: 147318 Code to Test Ratio: 1:1.1
  9. GemCollector Up-to-date Point • 依存 gem の最新度 ◦ この gem

    を使っているアプリケーションを探す by @eagletmt https://techlife.cookpad.com/entry/2018/06/08/080000
  10. background worker の削除 • cookpad 内のレガシー非同期処理システムを削除 ◦ resque 製非同期処理基盤 ◦

    モダン非同期処理基盤としては barbeque が整備されていたので移行 ▪ ECS を利用したオフラインジョブの実行環境 by @k0kubun https://techlife.cookpad.com/entry/2016/09/09/235007
  11. pantry の分割 • cookpad と pantry を分割 (cookpad_all 内で) ◦

    デプロイ先により挙動が変わる不思議なアプリを分割 ◦ 本質的に共有するものは多くなかった (切り離しはもちろん大変だった)
  12. 様々な Microservices アプリへの切り出し • 検索機能、料理きろく API、モバイルアプリ AB テスト用 API、ユーザ認証関連機能、など数々なアプリを cookpad_all

    から切り出し ◦ 切り出す単位は組織構造にフィットする、それでいてひとまとまりになってい て細かすぎないサイズ ▪ つまり「ちょうどいいサイズに」
  13. コード削除 • 不要コードを削除する ◦ がんばって不要コードを探して削除 ◦ Gemfile をジッと眺めて不要 gem を探す

    ◦ lazy loading を利用し不要 gem を検出 ◦ 棚卸し Issue の自動作成 ◦ Iseq 実行処理を記録し不要コードを探す
  14. lazy loading を利用し不要 gem を検出 • ruby に手を加え lazy loading

    利用し不要 gem を検出 ◦ Ruby の lazy loading の仕組みを利用して未使用の gem を探す by @riseshia https://techlife.cookpad.com/entry/2018/04/04/080000
  15. Iseq 実行処理を記録し不要コードを探す • ruby に手を加え Iseq 実行ログを記録し不要コードを探す ◦ 本番で記録したログを Redshift

    に蓄積 ◦ 詳細は近日中に @riseshia から techlife かどこかで発表など ◦ ruby 2.6 では素の ruby で可能になるかも ▪ Feature #15022 Oneshot coverage by @mame https://bugs.ruby-lang.org/issues/15022
  16. その他 • gem の更新 ◦ rails, rspec など様々な gem のアップグレード

    ◦ Machinist 1 -> FactoryBot 移行 ◦ リポジトリに埋め込まれていた改造 gem を捨てて OSS 最新版に更新 ◦ bootsnap の導入 • ruby アップグレード • EC2 インスタンスの式年遷宮 (CentOS 6 -> Ubuntu 16)