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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
140
dentaku - Ruby製の電卓CLI / dentaku - A Ruby CLI Calculator
hogelog
0
65
"複雑なデータ処理 × 静的サイト" を両立させる、楽をするRails運用 / A low-effort Rails workflow that combines “Complex Data Processing × Static Sites”
hogelog
3
6.6k
Javaアプリケーションの配布とパッケージング / Distribution and packaging of Java applications
hogelog
4
1k
なぜ Rack を理解すべきかプレトーク / Why should you understand Rack - Pre-talk
hogelog
0
460
ruby/irbへのコントリビュートと愉快な仲間たち / RubyKaigi 2024 Wrap Party
hogelog
0
270
RubyKaigi 2024 LT: Visualize the internal state of ruby processes in Real-Time
hogelog
0
340
Talk about CI and testing of the STORES
hogelog
2
640
小3の子がいるエンジニアの昔と今。
hogelog
0
1.8k
Other Decks in Technology
See All in Technology
ボトムアップ文化が強い組織で セキュリティをどう根付かせていくかの現在進行形の話 / Making Security Stick in a Bottom-Up Organization
yamaguchitk333
0
230
FPGAが実現する遠方宇宙の高空間分解能天体撮影 -大型地上望遠鏡の視力を補正する「補償光学」とは?-
komei_mt
0
270
ハーレムエンジニアリング
kazuma777777
0
170
ブラウザ研修 2026
recruitengineers
PRO
6
1k
Software Supply Chain Attackからクラウド環境を守るためにできること
lhazy
2
260
トヨタ⽣産⽅式(TPS)⼊⾨
recruitengineers
PRO
3
890
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
160
【AG-UI × A2UI × MCP Apps】Generative UIをやさしく解説する
nrinetcom
PRO
1
130
Goでデータパイプラインを作ろう
sansantech
PRO
1
470
Data Hubグループ 紹介資料
sansan33
PRO
0
3.2k
メルカリのグローバルアプリで挑んだ AlloyDB 運用と課題解決の実践記
hatappi
0
250
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
770
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
650
Designing for humans not robots
tammielis
254
26k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Designing for Performance
lara
611
70k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
200
Raft: Consensus for Rubyists
vanstee
141
7.6k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
290
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.7k
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