app server arena: a comparison of ruby application servers
DESCRIPTION
Slides from my presentation at Lonestar Ruby Conference 2013 entitled "App Server Arena". This presentation examined four basic characteristics (configuration, mode of operation, use cases and performance) across four application servers: Passenger, Unicorn, Thin and Puma. The actual graphs and numbers that I showed during the presentation aren't in the slides; they're in an Apple Numbers document that's available at the link below. Please forgive any formatting errors; the presentation was built in Keynote, and apparently slideshare doesn't want Keynote documents, so I had to export it to PowerPoint format. The accompanying source code for the application and a (very) detailed analysis can be found at GitHub: https://github.com/jaustinhughey/app-server-arenaTRANSCRIPT
![Page 1: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/1.jpg)
Engine Yard - www.engineyard.com
App Server ArenaApp Server ArenaComparison of Ruby Comparison of Ruby Application ServersApplication Servers
J. Austin HugheyField Application EngineerEngine Yard
@jaustinhughey
@openhackatx
@engineyard
![Page 2: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/2.jpg)
SHAMELESS PROMOTIONAL PLUG
August 8-9, San Franciscodistill.engineyard.com
25 SpeakersWicked awesome party called “Moonshine”- Application Architecture- UX- Testing- Security
![Page 3: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/3.jpg)
3Engine Yard - www.engineyard.com
• Lots of app servers out there, which one do you want to use and in what cases?
• Examine four app servers and look at:–Mode of Operation
–Use cases
–Configuration
–Performance
OverviewOverview
![Page 4: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/4.jpg)
4Engine Yard - www.engineyard.com
Let’s meet the gladiatorsLet’s meet the gladiators
• Passenger– widespread use, familiar to most developers, super easy
configuration
• Unicorn– in-memory forking, fast client/request execution
• Thin– EventMachine based application server
• Puma– concurrent request processing
– Engine Yard sponsored project
![Page 5: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/5.jpg)
5Engine Yard - www.engineyard.com
THE ARENATHE ARENA
• Basic Sinatra app with 5 request resources:– /server - display server information (very fast)
– /pi - compute Pi to 5,000 decimal places
• Mildly computationally expensive simulation
– /sleep - sleep 1, render a response (wait simulation)
• Trying to simulate I/O blocking without actually doing I/O, as well as try to create some request queuing
– /borat - uses Twitter API to get last 10 tweets from @devops_borat
• Twitter API really limited my tests here
• Trying to simulate real world network latency
– /random - one of the above (except /borat) at random
• Attempt to simulate multiple users of an application doing different things simultaneously
![Page 6: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/6.jpg)
6Engine Yard - www.engineyard.com
THE ARENA (cont.)THE ARENA (cont.)
• High CPU Medium on Amazon EC2– Engine Yard Gentoo stable-v4 stack; 3.4 kernel
– nginx, monit, Ruby 2.0.0
– 2 virtual CPU cores
– 1.7GB Memory
![Page 7: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/7.jpg)
PassengerVersion 3 - Version 4 not yet available on Engine Yard Cloud*
* We’re working on that.
![Page 8: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/8.jpg)
8Engine Yard - www.engineyard.com
Passenger: Fighting Style Passenger: Fighting Style (Operation)(Operation)
• Embeds itself into nginx or Apache– nginx is used in this example as Engine Yard doesn’t make use of
Apache
• Excels in running multiple applications on the same hardware by “elastic” management of worker processes by traffic needs– Can cause problems with “always on” applications that aren’t fully
configured
• Per-worker or global request queues• Can manually route requests to specific workers based on
their load, telling each worker which requests to work• Lots of configuration options
![Page 9: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/9.jpg)
9Engine Yard - www.engineyard.com
Passenger: Strategy (Use Cases)Passenger: Strategy (Use Cases)
• Good all around, fairly solid• Best at multiple apps on same hardware
– Only if apps are low to moderate traffic
• Many “advanced” features exist in open source alternatives for free, but are available in Passenger Enterprise– Multi-threaded requests (v4, Enterprise license)
• Puma
– Rolling restarts / zero-downtime deploys (Enterprise)
• Thin, Unicorn, Puma
• Capable of “resisting” deployment errors by refusing to sacrifice old processes for buggy new ones after a bad deploy
– Live IRB console - attach to Passenger worker pid with a REPL
• Unique to Passenger (strace is a kernel-level alternative)
![Page 10: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/10.jpg)
10
Engine Yard - www.engineyard.com
Passenger: Training Passenger: Training (Configuration)(Configuration)
• All configuration in nginx config files– /etc/nginx/nginx.conf, servers/appname.conf, etc.
• Compiled as a module with Apache, *directly* with nginx– Must get nginx source from Phusion with their changes, compile from
there since nginx has no “plugin” architecture
• Can configure for multiple applications or just one, all within nginx configuration
• Can pre-start application workers by spoofing a request to the application domain
• Recommended worker count: varies by application/environment - possibly (num_cores * 1.5).round, but may be a problem if running multiple apps
![Page 11: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/11.jpg)
Unicorn
![Page 12: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/12.jpg)
12
Engine Yard - www.engineyard.com
Unicorn: Fighting Style (Operation)Unicorn: Fighting Style (Operation)
• Spins up a master process, forks into N workers– master runs “before_fork” block
– each worker runs “after_fork”
• Master monitors workers for stability– kills anything that doesn’t respond in N seconds (configurable,
default: 30)
– simply forks itself again to replace failed worker
• All workers pull from a single socket on the local machine– nginx can put all requests into that socket, workers dip the socket for
requests
• No singular thread/process to route requests to workers– All done through the socket
![Page 13: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/13.jpg)
13
Engine Yard - www.engineyard.com
Unicorn: Strategy (Use Cases)Unicorn: Strategy (Use Cases)
• One app on hardware• Kills workers running long requests - bad choice for
websockets/long-polling (Thin would be better here)• Zero downtime deploy by QUIT+SIGUSR2 signal
– Reload master, which then kills old workers and forks itself again
• Less “WTF” than Passenger– Hopefully Passenger 4 makes that comparison totally unnecessary
![Page 14: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/14.jpg)
14
Engine Yard - www.engineyard.com
Unicorn: Training (Configuration)Unicorn: Training (Configuration)
• unicorn.rb– before_fork, after_fork, number of workers is configurable
• Binds to a Unix socket where nginx dumps requests• timeout: sets how long to wait on a request before killing the
worker• Recommended worker count: (num_cores * 1.5).round
– Add more if you have the CPU to handle it and it won’t push you close to swap
![Page 15: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/15.jpg)
(I really wish there was a high-res logo for this.)
![Page 16: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/16.jpg)
16
Engine Yard - www.engineyard.com
Thin: Fighting Style (Operation)Thin: Fighting Style (Operation)
• Similar to Unicorn• One socket per worker
– configure nginx to “round robin” the requests among N workers
• EventMachine based; can work well with long-running requests
• Can perform rolling worker restarts with “onebyone” option
![Page 17: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/17.jpg)
17
Engine Yard - www.engineyard.com
Thin: Strategy (Use Cases)Thin: Strategy (Use Cases)
• Single application on hardware• Well suited to long-running requests, live streaming,
websockets, etc. due to evented architecture
![Page 18: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/18.jpg)
18
Engine Yard - www.engineyard.com
Thin: Training (Configuration)Thin: Training (Configuration)
• One socket/port per worker• Have nginx “load balance” requests among said workers
with an upstream definition in configuration.• Can utilize a YAML configuration file:
– environment: “production”
– servers: 5 (number of workers in cluster mode)
– onebyone: true (rolling worker restarts)
– tag: appname-thin (specific string shows up in ps output)
• Recommended worker count: (num_cores * 1.5).round– Add more if you find that you have a lot of unused CPU and you can
do so without pushing your memory close to swap
![Page 19: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/19.jpg)
A MODERN, CONCURRENT WEB SERVER FOR RUBY
![Page 20: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/20.jpg)
20
Engine Yard - www.engineyard.com
Puma: Fighting Style (Operation)Puma: Fighting Style (Operation)
• Threaded request processing– Even on MRI, though still bound by GVL
– Can probably get better performance on JRuby/Rubinius
• Bind to ports or socket• One socket for all workers if using sockets• Runs a request in a new thread
![Page 21: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/21.jpg)
21
Engine Yard - www.engineyard.com
Puma: Strategy (Use Cases)Puma: Strategy (Use Cases)
• Anything that can benefit from truly concurrent execution is fair game to try Puma
• Computationally expensive tasks, not so much; tests show Puma falls over on computationally expensive operations
• Massive memory savings if running JRuby/Rubinius - one process handles everything that 5+ can
• Can do rolling restarts
![Page 22: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/22.jpg)
22
Engine Yard - www.engineyard.com
Puma: Training (Configuration)Puma: Training (Configuration)
• One socket for all requests (easier nginx configuration)• Master process spawns workers• Can handle rolling restarts via USR1
– Master spins up new workers, only switches to them if they start correctly - somewhat like Passenger Enterprise’s deploy failure resistance
• Specify the min:max number of threads when starting Puma– bundle exec puma -t X:Y
![Page 23: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/23.jpg)
LET THE GAMES BEGIN
![Page 27: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/27.jpg)
27
Engine Yard - www.engineyard.com
/sleep/sleep
![Page 28: App Server Arena: A Comparison of Ruby Application Servers](https://reader033.vdocuments.us/reader033/viewer/2022051816/5477890ab4af9fd77d8b47a6/html5/thumbnails/28.jpg)
28
Engine Yard - www.engineyard.com
/random/random