Go Reactive!

Preview:

DESCRIPTION

This talk will provide a high-level overview of Reactive web application development. Not only will the 'why' be covered, but also the 'how'. We'll explore a few concrete Reactive design patterns using code examples from Scala and Play, along with Play’s excellent Akka interoperability to demonstrate an underlying message-driven architecture. On that note, we'll discuss two distinct flavours of a message-driven architecture: event-driven and actor-based messaging, and how to pick the right one based on the common advantages and pitfalls of each. By the end of this session you should have a broad overview of why and how to build responsive, resilient, and scalable web applications, using an underlying message-driven architecture to ‘Go Reactive’.

Citation preview

Go Reactive!An Overview of the Reactive Programming Paradigm

Why do we need a different approach?

–Dan Kegel: The C10k Problem, 1999

“It’s time for web servers to handle ten thousand clients simultaneously.”

4

• The Internet had 280 million users

• No Facebook, no Twitter

• Snapshots of data, limited streaming

• Response times in seconds

• Downtime all the time

Party like it’s 1999

5

• Single machines, single cores

• Limited networking

• E.g, a mix of broadband, dialup internet, intranets

• Expensive memory, CPU, hard drives

Hardware in 1999

6

• “Small data” — i.e, megabytes, gigabytes

• The term “Big Data” was first used in the 1999 paper, “Visually exploring gigabyte

data sets in real time”, published in the Communications of the ACM

Hardware in 1999

– “Visually exploring gigabyte data sets in real time”, ACM, 1999

“Where megabyte data sets were once considered large, we now find data sets from individual simulations in the 300GB range.”

–Dan Kegel: The C10k Problem, 1999

“In 1999, one of the busiest FTP sites, cdrom.com, handled 10,000 clients simultaneously through a Gigabit Ethernet pipe.”

15 years later.

Expectations have changed. Hardware has changed.

–Scott Andreas, Urban Airship

“If one node can only serve 10,000 clients, the venture is cost-prohibitive from the start – just one million devices would require a fleet of 100

servers.”

12

• 1999 — Internet, 280 million users

• 2005 — Internet, 1 billion users

•2014 — Internet, 2.95 billion users

The Internet in 2014

13

• 1999 — MySpace? Friendster? GeoCities? LiveJournal?

• 2014 — Twitter, 270 million users

•2014 — Facebook, 1.1 billion users

Web applications in 2014

Facebook alone now handles the user-base of four Internets circa 1999.

Hardware and data in 2014

15

• A single machine ⇨ clusters of machines

• A single core ⇨ multiple cores

• Slow networks ⇨ fast networks

• Small data snapshots ⇨ big data, streams of data

Realities of modern software development — 2014

16

• Applications are distributed

• Applications are composed

• Users expect responsiveness — “a slow application is a dead application”

• Users expect adaptation — UIs must adapt to multiple screen sizes and input types

Developers can no longer avoid parallelism and concurrency.

In 2010, Urban Airship used Java NIO to successfully test 512,000+ concurrent connections on a single 2.5 GB EC2 instance.

C10k ⇨ C500k

(Not so fast…)

–Mihai Rotaru, 2013, discussing MigratoryData WebSocket server

“MigratoryData scales up to 12 million concurrent users from a single Dell PowerEdge R610 server while pushing up to 1.015 Gbps live data

(each user receives a 512-byte message every minute).”

C10k ⇨ C12m

What are the principles of Reactive application development?

–Jonas Bonér

“Instead of the latest framework of the day or the latest buzzword, Reactive brings the talk back to core principles; the design, the

architecture, the way we think about building software.”

Core principles of reactive application development

24

• React to events ⇨ Message-driven ⇨ The foundation

• React to load ⇨ Scalable ⇨ A trait

• React to failure ⇨ Resilient ⇨ A trait

• React to users ⇨ Responsive ⇨ The goal

Reactive applications

25

re·spon·sive !

“Reacting quickly and positively.” !

synonyms: quick to react to, reactive to, receptive to, open to suggestions about, amenable to, flexible to, sensitive to, sympathetic to

Responsive — flexibility

27

Progressive UI enhancement

• Never allow slow external dependencies to degrade the user experience

Blue skies

• Never assume blue skies, assume grey skies

Responsive — quick to react

28

Four combinations

• Asynchronous and non-blocking

• Asynchronous and blocking

• Synchronous and non-blocking

• Synchronous and blocking

• Spot the problem combination

Asynchronous vs synchronous processing times

29

Process 1

Process 2

Process 3

0 ms 425 ms

200 ms

75 ms

150 ms

Asynchronous - 200ms

Process 1 Process 2 Process 3

0 ms 425 ms

Synchronous - 425ms

• Staying async — and in the future — ensures that processing time is not bounded by IO

• Async processing is limited by only the longest running process

• Synchronous processing is limited by the combined processing times

• Stay async!

Responsiveness with

31

1. mydomain.com/admin/settings

renders views.html.admin HTML

2. Browser fetches static assets served

from outside of Play

3. Ajax requests — Play serves JSON

via a RESTful API

HTML for views.html.admin(...)

Browser Play

CDN

HTTP GET (mydomain.com/admin/settings)

JS, CSS, images, etc

HTTP GET (mydomain.com/ws/some/services)

JSON

Example template with AngularJS

32

• Scala template rendered by Twirl and returned by Play controller

• HTML inserted into ng-view by Angular controller after initial page render

@(customer: Customer)!!<head>...</head>!<body>! <div class="wrapper">! <header>…</header>! <h1>Welcome @customer.name!</h1>! <section id="body" ng-app="ngAdmin">! <div ng-view></div>! </section>! <footer>...</footer>! </div>!</body>!</html>

HeaderPlay handles navigation

Footer

load async || fail whale

load async || omit

AngularJS

Responsiveness !

Being quick to react to all users of a system — under blue skies and grey skies — in order to ensure a consistent experience.

scal·able !

“Capable of being easily expanded or upgraded on demand.” !

synonyms: ascendable, climbable, extensible, expandable, expansible, adaptable, elastic, flexible

Scalable — terms

35

• Performance is a measurement of response time — the goal

• Load impacts performance if not handled properly — the enemy

Scalable — how to deal with load?

36

• Scale up — faster CPU, more memory, bigger hard drive

• More efficient use of existing resources

• Scale out — distribute work across workers

• Elasticity, provisioning new resources on demand

• Location transparency

Scalability with

38

• Actors can communicate across thread boundaries and across network boundaries

• Pure message passing enables distribution

• Distribution provides concurrency

Actor Mailbox

IsolatedState

Actor Mailbox

IsolatedState

Scalable — Location transparency

39

class GameActor extends Actor {! def receive = {! case handshakeRequest: HandshakeRequest => ! sender ! computeHandshakeResponse(handshakeRequest)! case turnMessage: TurnMessage => ! sender ! computeTurnResponse(turnMessage) ! }!}!

!

• Time, space, mutation ⇨ flow, events, messages

Scalable — Akka actor example

Reference Architecture

40

PlayServer

AkkaMasterRouter

AkkaStandbyRouter

AkkaWorker

AkkaWorker

AkkaWorker

AkkaWorker

PlayServer

PlayServer

PlayServer

https://typesafe.com/activator/template/akka-distributed-workers

Scalable — Akka remoting

41

• Creating a remote actorval ref = system.actorOf(FooActor.props.withDeploy(Deploy(scope = RemoteScope(address))))!

• Referencing a remote actorval remoteFooActor = context.actorSelection("akka.tcp://actorSystemName@10.0.0.1:2552/user/fooActor")

42

akka {! actor {! provider = "akka.remote.RemoteActorRefProvider"! }! remote {! transport = "akka.remote.netty.NettyRemoteTransport"! netty {! hostname = "127.0.0.1"! port = 2552! }! }!}

Scalable — Akka remoting example config

Scalability !

The capability of your system to be easily upgraded on demand in order to ensure responsiveness under various load conditions.

re·sil·ient !

“Able to withstand or recover quickly from difficult conditions.” !

synonyms: strong, tough, hardy

Resilient

45

Bulkheads • Partitioning — partition thread groups for different functionality

Circuit Breakers • Stability — Failing external dependencies shouldn’t bring down an entire app

Backpressure • Throttling — wait for a consumer to demand more work to avoid fast producers

overwhelming slow consumers

• Example: http://typesafe.com/activator/template/akka-stream-scala

Resilience with

Circuit Breaker

47

Closed

OpenHalf-Open

attemptreset

trip reset

Play — BlockingCircuitBreaker.scala

48

import akka.pattern.CircuitBreaker!import play.api.libs.concurrent.Akka!import play.api.Play.current!import scala.concurrent.duration.DurationInt!!object BlockingCircuitBreaker {! val circuitBreaker = {! val maxFailures = current.configuration.getInt(“properties.cb.maxFailures").getOrElse(1)! val callTimeout = current.configuration.getInt(“properties.cb.callTO").getOrElse(10)! val resetTimeout = current.configuration.getInt(“properties.cb.resetTO").getOrElse(100)! val cb = new CircuitBreaker(! executor = ThreadPools.blockingPool,! scheduler = Akka.system.scheduler,! maxFailures = maxFailures,! callTimeout = callTimeout.milliseconds,! resetTimeout = resetTimeout.milliseconds! )! cb.onOpen(someAlertOperation)! cb! }!}!

Play — How to handle failure?

49

package object circuitbreaker { ! def catchOpenCircuitBreaker(r: Future[Result]): Future[Result] = { ! r recover { case _: CircuitBreakerOpenException => {! Results.InternalServerError(…)! }! }! }!}!

Play — Controller-tier

50

import circuitbreakers.BlockingCircuitBreaker.circuitBreaker.withCircuitBreaker!!val futureResult = withCircuitBreaker({…})!!catchOpenCircuitBreaker {! futureResult.map { r =>!! Results.Ok(…)! }!}!

Why circuit breakers?

51

• Prevent failures from overwhelming strained services and cascading

• Codify strategies to address the inevitable failure of external systems

• Prepare for failure early

• Play + Akka + Circuit breakers provides an extremely resilient web foundation!

Resiliency !

The proper application of fundamental design and architecture principles to ensure responsiveness under grey skies.

e·vent !

“Something that happens or is regarded as happening; an occurrence, especially one of some importance.”

!

driv·en !

“Propelled or motivated by something.”

Traditional concurrency

54

Thread based concurrency with objects and shared state • Imperative, sequential execution

• Threads for concurrency

• Mutable objects, shared state

• Most common paradigm

• Implementations — Java Enterprise Edition, Wicket, etc

Traditional concurrency

55

Software transactional memory (STM) • Immutable values

• Atomicity, consistency, isolation and durability

• Cannot perform any operation that cannot be undone, including (most) I/O

• Think command pattern/interface

• Implementations — Haskell STM (native), libs for Scala, Java, OCaml, Clojure, etc

Share nothing concurrency

56

Event-driven concurrency • Thread based event loops

• Typically single threaded

• Implementations — Node.js, Twisted Python, EventMachine (Ruby)

Share nothing concurrency

57

Actor-based concurrency • Mutable state, but completely isolated (state can only be mutated by the actor)

• Asynchronous message passing between actors using mailboxes

• Implementations — Erlang, Akka

Events versus messages

58

• Events happen

• Interested observers must watch for and respond to events

• Anonymous function callbacks lead to the deeply nested “pyramid of doom”

• Messages are directed

• Messages can be directed to one receiver or broadcast to a number of receivers

• Directed messages avoid the pyramid of doom

Message-driven !

A message-driven architecture forces programmers to deal with scalability and resilience at a code level in order to facilitate

responsiveness.

re·ac·tive !

“Responsive to stimulus.” !

synonyms: active, aware, conscious, receptive, sensitive, acknowledging, alive, answering

Reactive

61

Erlang has embraced the tenets of reactive programming since 1985.

Erlang characteristics and use cases

63

• Share nothing architecture — processes cannot share data

• Pure message passing — copy all the data you need in the messages

• Crash detection and recovery — things will crash, so let them crash then recover

Erlang characteristics and use cases

64

Popular Erlang Software • Wings 3D — 3D modelling • Ejabberd — instant messaging server • CouchDB — document database • RabbitMQ — enterprise-y messaging

Erlang in Production • Ericsson — 3G mobile networks

• Amazon — SimpleDB, EC2

• Facebook — back-end chat server

• T-Mobile — SMS and authentication

–Jonas Bonér

“Reactive looks back in history. It doesn't ignore the goldmine of knowledge that's been around for 30 to 40 years, but rather tries to bring

it into new context.”

Sources and credits

66

• Jonas Bonér — Reactive Supply to Changing Demand

• Joe Armstrong — K things I know about building Resilient Reactive Systems

• Benjamin Erb — Concurrent Programming for Scalable Web Architectures

• Rich Hickey — The Value of Values

• Plus various talks, papers, books, blog posts, and tweets by Dean Wampler, Erik Meijer, Martin Odersky, Martin Thompson, and many more

©Typesafe 2014 – All Rights Reserved

Recommended