Typesafe trainer and consultant Will Sargent describes just how Play Framework is so "fast" for Java and Scala production apps.
More Play, Akka, Scala and Apache Spark webinars, presentations, and videos:
http://typesafe.com/resources/videos
5. 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
6. 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
8. Imagine a CPU core as a paper shredder
Reactive Applications 8
9. If you have to get more paper (IO), the shredder
idles
Reactive Applications 9
10. Worst case - Single Threaded Model
Reactive Applications 10
11. 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
14. 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
16. 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
17. 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
18. 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
22. 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
23. 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
24. Work Stealing in Action – no idle threads!
Reactive Applications 24
25. 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
26. 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
27. 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
28. 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
figuration
Reactive Applications 28
29. What about Play in Tomcat using
Play2WAR?
Reactive Applications 29
30. 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
31. 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
32. 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