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
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
hogelog
November 14, 2024
Technology
1.3k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby Web Application 50 Times Faster
hogelog
November 14, 2024
More Decks by hogelog
See All by hogelog
スマホでゲームをするか、漫画を読むか、開発をするか / Gaming, Reading or Coding on my phone.
hogelog
1
130
dentaku - Ruby製の電卓CLI / dentaku - A Ruby CLI Calculator
hogelog
0
55
"複雑なデータ処理 × 静的サイト" を両立させる、楽をするRails運用 / A low-effort Rails workflow that combines “Complex Data Processing × Static Sites”
hogelog
3
6.2k
Javaアプリケーションの配布とパッケージング / Distribution and packaging of Java applications
hogelog
4
990
なぜ Rack を理解すべきかプレトーク / Why should you understand Rack - Pre-talk
hogelog
0
450
ruby/irbへのコントリビュートと愉快な仲間たち / RubyKaigi 2024 Wrap Party
hogelog
0
250
RubyKaigi 2024 LT: Visualize the internal state of ruby processes in Real-Time
hogelog
0
330
Talk about CI and testing of the STORES
hogelog
2
630
小3の子がいるエンジニアの昔と今。
hogelog
0
1.7k
Other Decks in Technology
See All in Technology
2026-06-24_人とAIの責務分離に基づく開発プロセスの提案.pdf
takahiromatsui
0
250
「勝手に広まる」人気 AI エージェントを爆速で作ろう!(AWS Summit Japan 2026講演資料)
minorun365
PRO
10
2.6k
iOS アプリの「これって不具合ですか?」を AI に調べてもらう
miichan
0
150
組織における AI-DLC 実践
askul
0
170
自作お家AIエージェントスタックチャンFWで困っている所紹介
74th
0
150
When Platform Engineering Meets GenAI
sucitw
0
200
Zenoh on Zephyr on LiteX
takasehideki
2
130
AIをフル活用してオンコール機能のプロトタイプを2日で作った話 / Building an AI-Powered On-Call Prototype in Just Two Days
nari_ex
0
150
秘密度ラベル初心者が第1歩でつまづかないための「設計・運用」ポイント
seafay
PRO
1
520
いまさら聞けない「仕様駆動開発入門」 〜AI活用時代の開発プロセスを考える〜
findy_eventslides
2
230
AIエージェントとPhysical AIが拓く製造業の変革(ハノーバーメッセリキャップ)
iotcomjpadmin
0
170
Why is RC4 still being used?
tamaiyutaro
0
150
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
KATA
mclloyd
PRO
35
15k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.6k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
How GitHub (no longer) Works
holman
316
150k
The Cult of Friendly URLs
andyhume
79
6.9k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Transcript
@hogelog 2024-11-14 STORES.rb Railsのはなし RubyのWebアプリケーションを50倍速くする方法
なまえなど 2 - @hogelog (GitHub, Twitter X, 社, …) -
小室 直 (Komuro Sunao) - STORES 株式会社 ソフトウェアエンジニア
今日する話 3 - Ruby製Webアプリケーションを高速化します - 1 processでの処理性能を計測 - ローカル環境 (Apple
M1 Max) で検証 - 一部実装はGitHubにpush済 https://github.com/hogelog/example-storesrb-ruby-webapp-tuning - 対象は最近ホットなCSP (Content Security Policy) レポートを 受け取るだけのWebアプリケーション
Content Security Policy (CSP) とは 4 - Content-Security-Policyヘッダを付与することで ブラウザが読み込むリソースを制限できる機能 -
XSS攻撃の軽減とレポーティングなどが可能 - レポートをHTTP経由で受け取り - 詳しくは https://developer.mozilla.org/docs/Web/HTTP/CSP
対象Webアプリケーションの仕様 5 - CSPレポート (application/csp-report) を受け取って 標準出力に表示 - その後集計してレポーティングする想定 -
エンドポイントは POST /reports
1. モノリシックRailsアプリケーションに実装
モノリシックRailsアプリケーションに実装 7 - CSPを設定するネットショップモノリシックRailsに レポート用エンドポイントを組み込み class ReportsController < ApplicationController skip_before_action
:verify_authenticity_token def create payload = JSON.parse(request.body.read) message = { time: Time.zone.now. to_s, report: payload[ "csp-report" ], } $stdout .puts JSON.generate(message) head :created end end
モノリシックRailsアプリケーション実装のベンチマーク結果 8 - 289.47 requests/sec - はたして50倍速くすることはできるのか $ wrk -t5
-d10s -s wrk.lua http://localhost:3000 Running 10s test @ http://localhost:3000 5 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 34.22ms 6.76ms 72.72ms 67.41% Req/Sec 58.00 13.03 101.00 68.40% 2914 requests in 10.07s, 10.41MB read Non-2xx or 3xx responses: 2914 Requests/sec: 289.47 Transfer/sec: 1.03MB
2. 新規Railsアプリケーション
新規Railsアプリケーションで実装 10 - ` rails new csp-report-collector --api --minimal --skip-test
--skip-active-record ` - POST /reports 実装は同様なので省略 - 5550.35 requests/sec -> 19倍 $ wrk -t5 -d10s -s wrk.lua http://localhost:3000 Running 10s test @ http://localhost:3000 5 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.97ms 11.95ms 56.79ms 79.94% Req/Sec 1.12k 232.43 1.73k 67.80% 55754 requests in 10.05s, 21.52MB read Requests/sec: 5550.35 Transfer/sec: 2.14MB
新規Railsアプリケーションの改善ポイント 11 - モノリシックRailsアプリケーション - POST /reports には不要な大量のライブラリ - 様々なコールバック、Rackミドルウェアなど
- Pitchfork (1processの同時処理は1リクエスト) - 新規Railsアプリケーション - APIモードの最小限のRailsのみ利用 - Puma (1 process, 3 threads)
3. 新規Railsアプリケーションのチューニング
新規Railsアプリケーションをチューニング 13 - Rackミドルウェアを可能な限り削除 (ActionDispatch::HostAuthorization, Rack::Sendfile, ActionDispatch::Static, ActionDispatch::ServerTiming, Rails::Rack::Logger, ActionDispatch::RequestId,
ActionDispatch::RemoteIp, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::ActionableExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, Rack::ETag, Rack::Head, Rack::Runtime, Rack::ConditionalGet, ActionDispatch::Executor ) - Puma: 1 process, 2 threadsに調整 - 11071.26 requests/sec -> 38倍 $ wrk -t5 -d10s -s wrk.lua http://localhost:3000 Running 10s test @ http://localhost:3000 5 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 14.11ms 18.67ms 62.85ms 78.87% Req/Sec 2.23k 622.10 3.08k 46.40% 111464 requests in 10.07s, 32.56MB read Requests/sec: 11071.26 Transfer/sec: 3.23MB
新規Railsアプリケーションのチューニングポイント 14 - 処理を限りなく薄くするためRackミドルウェアを削除 - active_model/railtie, action_view/railtie も - アプリケーション傾向からスレッド数を調整
(3 -> 2) - スレッド数についてはKaigi on Rails 2024 “都市伝説 バスターズ「WebアプリのボトルネックはDBだから言 語の性能は関係ない」” がわかりやすいです
4. Railsをやめてみる
RailsをやめてRackアプリとして実装 16 - Rackアプリケーションとして POST /reportsを実装 require "json" class App
def call(env) if env["REQUEST_METHOD" ] == "POST" && env["PATH_INFO"] == "/reports" return handle_report(env[ "rack.input" ]) end [404, {}, [ ""]] end def handle_report (body) payload = JSON.parse(body.read) message = { time: Time.now. to_s, report: payload[ "csp-report" ], } $stdout .puts JSON.generate(message) [201, {"content-type" => "application/csp-report" }, [""]] end end
Rackアプリケーションのベンチマーク結果 17 - Puma: 1 process, 2 threads - 24257.29
requests/sec -> 84倍 🎉 $ wrk -t5 -d10s -s wrk.lua http://localhost:3000 Running 10s test @ http://localhost:3000 5 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 13.71ms 18.33ms 68.44ms 78.95% Req/Sec 4.88k 1.32k 6.68k 49.00% 244153 requests in 10.07s, 18.89MB read Requests/sec: 24257.29 Transfer/sec: 1.88MB
Rackアプリケーションの改善ポイント 18 - Puma, Rackアプリケーションという最小限のコードしか 動いていない - YJIT、GC調整などで更に高速化は目指せるかもしれない
ふりかえり 19 - 歴史を捨て、Railsを捨てることでWebアプリケーショ ンを50 84倍高速化することは可能🎉 - 歴史が詰まったモノリシックRailsアプリケーショ ンには色々なロジックが詰まっている -
Railsにも色々詰まっている - Q. 本当にRack版アプリケーションを運用する? - A. 現実的な選択肢にあげても良いなと思う
検証しててわかった嬉しいこと: json gemの高速化 20 - json 2.7.2: 23522.80 req/s -
json 2.8.1: 24257.29 req/s