What Makes Play Framework Fast
What Makes Play Framework Fast
Fast?
Will Sargent
Training & Consulting
What is “Fast?”
Applications written using Play Framework
will do more with the same hardware.
How?
In the Beginning (1990s)
• When Java was invented
• A computer had one CPU, with one core
• Concurrency, but no parallelism (literally cannot run 2 threads at once)
• Most concurrent access was based around synchronized locks....
• ...and people expected much less from the World Wide Web.
Reactive Applications 5
CPUs in 1999
• CPUs are the engine
• Execute work when they have data
• Sleep when they don’t have data
Reactive Applications 6
Computers Then
Reactive Applications 7
Imagine a CPU core as a paper shredder
Reactive Applications 8
If you have to get more paper (IO), the shredder
idles
Reactive Applications 9
Worst case - Single Threaded Model
Reactive Applications 10
Threads
• Threads keep data in memory until the CPU can execute it
• The more threads you have, the more memory you need
• But if the CPU is idle, then you may as well process it.
Reactive Applications 11
More people (threads) == happy shredder
Reactive Applications 12
Computers Now
Reactive Applications 13
Multicore CPUs makes threading vital
• Xeon E5-2699v3 has 18 cores on a single CPU, may have 2 CPUs
• 36 cores available
• Multiple cores mean that requests can be processed in parallel
Reactive Applications 14
Parallelism: Doing multiple things
Reactive Applications 15
Tomcat is a Servlet Container
• Servlets
• were invented in 1997
• Thread per Request model (will explain in next slide)
Reactive Applications 16
Thread per Request Model
• Advantages
• Useful for ThreadLocal (putting extra data into thread from request)
• Disadvantages
• 1 to 1 requirement between a thread and a request!
• If the request is kept open, the thread has to wait until it closes or gives
data!
• This means cannot use Comet, AJAX, SSE, Websocket, etc.
• Servlet 3.x attempts async model, but no Websocket support
Reactive Applications 17
Thread per Request Model
• Let’s keep going with the analogy:
• The CPU is a paper shredder – if it’s not being fed pages, it’s idle.
• In thread per request, the person ferrying pages can only get pages
from one person, and has to wait otherwise.
Reactive Applications 18
Thread Per Request == one book for one
thread
Reactive Applications 19
If a request is slow, means one fewer
thread!
No pages!
Reactive Applications 20
ThreadLocal means state tied to thread!
Session A
Session B
Reactive Applications 21
New advances in Java
• NIO – non blocking IO
• Released in JDK 1.4 (2002)
• NIO.2 came out in JDK 1.7 (2011)
• STILL not used in many applications for backwards compatibility
• java.util.concurrent
• Released in JDK 1.5 (2004)
• High performance thread pools and ExecutionContext
• But came out after most J2EE app servers were already architected.
Reactive Applications 22
Play is an Async, Non-Blocking HTTP server
• Asynchronous
• “Not guaranteed to happen in the order you run it”
• “Shred these five documents, I don’t care in which order it happens.”
• Can be parallel if you have multiple cores (i.e. five shredders)
• Non-blocking
• “If you’re waiting on something, give up the core until you have data”
• “Don’t hog the shredder if you’re out of paper.”
Reactive Applications 23
Work Stealing in Action – no idle threads!
Reactive Applications 24
Why is Play Faster?
• Responsive
• Uses Futures and Thread Pools to let CPU go at full throttle
• Uses NIO.2 through Netty to avoid blocking on network IO
• Stateless (no HTTP session), short lived objects for better GC
• No ThreadLocal anywhere
• Typically under 500 MB footprint
• Resilient
• Operations Friendly
• Deploys as a standalone RPM / Debian / tar.gz bundle
• Bounce server in seconds, no Java EE overhead
• Behaves like any other Unix process
Reactive Applications 25
Why is Play Faster?
• Elastic
• Start as many Play instances as you need, scales with your hardware
• Stop and restart Play servers as you feel like (it’s all stateless)
• Typesafe ConductR will do the grunt work for you
• Message Driven
• Play integrates seamlessly with Akka
• WebSocket / Ajax / Server Sent Events are handled through Actors
• Backend communication through Akka or Play WS (REST API)
• Experimental integration with Akka Streams coming in 2.4
Reactive Applications 26
How do I package a Play application?
• $ activator package:packageBin
• Produces a Debian package
• $ activator rpm:packageBin
• Produces an RPM package
• $ activator universal:packageZipTarball
• Produces a gzipped tarball
• $ activator docker:publishLocal
• Produces a docker image
• https://www.playframework.com/documentation/2.3.x/ProductionDist
Reactive Applications 27
How do I run Play in production?
• The distribution includes a shell script, under ./bin/yourapp
• You should run Play as a reverse proxy behind an http server, like
nginx.
• https://www.playframework.com/documentation/2.3.x/ProductionCon
figuration
Reactive Applications 28
What about Play in Tomcat using
Play2WAR?
Reactive Applications 29
Why not Tomcat?
• Servlet containers like Tomcat have architectural problems at their
core.
• Wasteful of CPU
• Thread per request model (until 3.x) ties a thread directly to request
• Even in 3.x, slower than native according to the Play2WAR
documentation.
• Wasteful of memory
• Not stateless, b/c servlet API has httpRequest.getSession
• Historically many “web” library used ThreadLocal & stateful patterns
• Not always obvious when libraries use ThreadLocal under the hood.
Reactive Applications 30
More interesting stuff…
Managing Library
Get in touch with How LinkedIn Uses
Dependencies with
Typesafe today! Play Framework
Play, sbt & Activator