What Makes Play Framework Fast? Will Sargent Training & Consulting
What Makes Play Framework
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
• Best case scenario
• You give data to the CPU just as it needs it
• Your CPU will run close to 100% and never sleep...
• ...execute all the work as fast as possible
• ...and then drop down to 0% once it’s done.
• Even in 1999, the problem was feeding a CPU enough data
• IO (disk / network) is too slow, not enough data to feed CPU
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.
• Still works even when you have only one CPU!
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
• Imagine each core as a paper shredder
• Some documents are larger and need more shredding (balancing work)
• Ensure everyone gets access to a shredder eventually (fairness)
• Ensure that no-one gets stuck or behaves badly
• Ensure that everyone gets served in a timely manner (responsive)
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)
• Pretty good at the time
• Single CPU means nothing runs in parallel
• Enough threads, enough memory, and you can keep feeding the CPU
Reactive Applications 16
Thread per Request Model
• A thread is created or retrieved from a pool for every HTTP request.
• The thread is bound to the request for the request’s lifetime.
• 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.
• Work/data is a set of pages to be shredded.
• A thread ferries around pages until it has access to the shredder.
• A request is someone holding a book, and offering a few pages at a
time.
• 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!
Reactive Applications 20
No pages!
ThreadLocal means state tied to thread!
Reactive Applications 21
Session B
Session A
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.”
• Play uses a fork join execution context with work stealing
• Does not bind a thread to a request – happy threads!
• “If you need paper, you can get it from anyone who has paper”
• Async + Non-Blocking = Responsive
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
• Responsive + Resilient + Elastic + Message Driven = Reactive
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
• Running the app generates a file with the process id:
• ./bin/yourapp -Dpidfile.path=/var/run/play.pid
• Stopping the app is done by killing the process:
• kill $(cat /var/run/play.pid)
• Play needs Java to be installed on the server, preferably Oracle JDK
1.8.
• You should run Play as a reverse proxy behind an http server, like
nginx.
• Use several nginx instances behind a load balancer, like haproxy.
• https://www.playframework.com/documentation/2.3.x/ProductionCon
figurationReactive 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…
HOW TO VIDEO
Managing Library
Dependencies with
Play, sbt & Activator
WATCH NOW
HAVE QUESTIONS?
Get in touch with
Typesafe today!
CONTACT US
SUCCESS STORY
How LinkedIn Uses
Play Framework
READ NOW
EXPERT TRAINING
Delivered on-site for Akka, Spark, Scala and Play
Help is just a click away. Get in touch
with Typesafe about our training courses.
• Intro Workshop to Apache Spark
• Fast Track & Advanced Scala
• Fast Track to Akka with Java or
Scala
• Fast Track to Play with Java or
Scala
• Advanced Akka with Java or Scala
Ask us about local trainings available by
24 Typesafe partners in 14 countries
around the world.
CONTACT US Learn more about on-site training
©Typesafe 2014 – All Rights Reserved