reactive web-applications @ lambdadays

71
Scala, Akka, Play The why and how of reactive web-applications on the JVM Lambda Days 2015 Manuel Bernhardt - @elmanu

Upload: manuel-bernhardt

Post on 21-Apr-2017

4.948 views

Category:

Engineering


3 download

TRANSCRIPT

Page 1: Reactive Web-Applications @ LambdaDays

Scala, Akka, PlayThe why and how of reactive web-applications on the JVM

Lambda Days 2015Manuel Bernhardt - @elmanu

Page 2: Reactive Web-Applications @ LambdaDays

Agenda1. The Why

2. The How

Page 3: Reactive Web-Applications @ LambdaDays

Who is speaking?

• freelance software consultant based in Vienna

• Vienna Scala User Group

• web, web, web

Page 4: Reactive Web-Applications @ LambdaDays

Who is speaking?

• freelance software consultant based in Vienna

• Vienna Scala User Group

• web, web, web

• writing a book on reactive web-applications

http://www.manning.com/bernhardt

Page 5: Reactive Web-Applications @ LambdaDays

The Why

Page 6: Reactive Web-Applications @ LambdaDays

The WhyThe Whys

Page 7: Reactive Web-Applications @ LambdaDays

1st Why: it's 2015, the year of...

Page 8: Reactive Web-Applications @ LambdaDays

2015!

Flying cars?Hoverboards?

Self-lacing shoes?

Page 9: Reactive Web-Applications @ LambdaDays

2015: many-core CPUs

• End of the single-core multi-core era

• Many players in the space

• Tilera, Cavium

• Adapteva Parallela

• Xeon PHI

• It's happening!

Page 10: Reactive Web-Applications @ LambdaDays

Too many cores?

• 1981 "640 kb ought to be enough for anybody" ~ Bill Gates

Page 11: Reactive Web-Applications @ LambdaDays

Too many cores?

• 1981 "640 kb ought to be enough for anybody" ~ Bill Gates

• 2014 "4 cores ought to be enough for anybody" ~ Linus Torvalds1

1 http://highscalability.com/blog/2014/12/31/linus-the-whole-parallel-computing-is-the-future-is-a-bunch.html

Page 12: Reactive Web-Applications @ LambdaDays

2nd Why: distribution is the norm, not the

exception

Page 13: Reactive Web-Applications @ LambdaDays

It's all in the cloud

• divide & conquer: specialized services that do one thing well

• storage: S3

• emails: MailChimp

• monitoring: New Relic, Plumbr

• etc. etc. etc.

Page 14: Reactive Web-Applications @ LambdaDays
Page 15: Reactive Web-Applications @ LambdaDays

This is not the cloud

Page 16: Reactive Web-Applications @ LambdaDays

That's more like the cloud

• scaling out to handle large loads

• scaling out / replication to handle node failure

Page 17: Reactive Web-Applications @ LambdaDays

Yes! That's the cloud!

• networks, networks, networks

• they fail all the time

• Jepsen series3

3 http://aphyr.com

Page 18: Reactive Web-Applications @ LambdaDays

The cloud is hard

• CAP theorem

• 8 fallacies of distributed computing

• hard problem, no easy solution

• PAXOS, CQRS, CRDTs

Page 19: Reactive Web-Applications @ LambdaDays

3rd Why: Winter is coming

Page 20: Reactive Web-Applications @ LambdaDays
Page 21: Reactive Web-Applications @ LambdaDays

Side note: Internet of Lost Things

Prediction: "By 2020, everyone will have a bunch of online things lost in their appartment"

Page 22: Reactive Web-Applications @ LambdaDays

4th Why: Houston, we have a problem

Page 23: Reactive Web-Applications @ LambdaDays

Our traditional programming tools don't work in this setting

Page 24: Reactive Web-Applications @ LambdaDays

We have been brainwashed to use:

1. imperative programming with mutable state

2. locks, locks, locks

Page 25: Reactive Web-Applications @ LambdaDays

The problem with mutable state

car.setPosition(0);car.setPosition(10);

Page 26: Reactive Web-Applications @ LambdaDays

The problem with mutable state

Page 27: Reactive Web-Applications @ LambdaDays

The problem with locks

• solution workaround for a broken conceptual model

• hard to reason about

• performance hit

Page 28: Reactive Web-Applications @ LambdaDays

The problem with object-orientation in Java

• there is no notion of time, only an illusion thereof

• changes to a mutable model only make sense locally if nobody is watching

• the larger the scope, the harder it gets to prevent inconsistencies

Page 29: Reactive Web-Applications @ LambdaDays

The Whys1. many-core CPUs are here

2. everything is distributed

3. IoT around the corner with 26 billions devices

4. our traditional approach does not work here

Page 30: Reactive Web-Applications @ LambdaDays

The How

Page 31: Reactive Web-Applications @ LambdaDays

The HowThe Hows

Page 32: Reactive Web-Applications @ LambdaDays

In theory

• Functional Programming

• The Actor Model

• Evented Server Model

• Stateless architecture

• Event Sourcing

• Reactive Streams

Page 33: Reactive Web-Applications @ LambdaDays

In practice

• Functional Programming � Scala• The Actor Model � Akka• Evented Server Model � Play• Stateless architecture � Play• Event Sourcing � Akka Persistence• Reactive Streams � Akka Streams

Page 34: Reactive Web-Applications @ LambdaDays

1st How: Functional Programming � Scala

Page 35: Reactive Web-Applications @ LambdaDays

Short Scala history

• Martin Odersky, EPFL

• first release in 2003

• Typesafe Inc.

Page 36: Reactive Web-Applications @ LambdaDays

Design goals• Full interoperability with Java

• Cut down boilerplate

• Pure object orientation & functional programming

• Move away from null

• Many-core programming

Page 37: Reactive Web-Applications @ LambdaDays

Core concepts of Functional Programming• immutability

• functions

• transforming data with functions

Page 38: Reactive Web-Applications @ LambdaDays

Immutability

case class Car(brand: String, position: Int)

val car = Car(brand = "DeLorean", position = 0)val movedCar = car.copy(position = 10)val movedCarLaterOn = car.copy(position = 30)

Page 39: Reactive Web-Applications @ LambdaDays

Immutability

case class Car(brand: String, position: Int)

val car = Car(brand = "DeLorean", position = 0)val movedCar = car.copy(position = 10)val movedCarLaterOn = car.copy(position = 30)

Work with snapshots of state

Page 40: Reactive Web-Applications @ LambdaDays

Higher-order functions

val (minors, majors) = users.partition(_.age < 18)

Page 41: Reactive Web-Applications @ LambdaDays

Higher-order functions

val isMinor = (age: Int) => age < 18

val (minors, majors) = users.partition(isMinor)

Page 42: Reactive Web-Applications @ LambdaDays

Higher-order functions

val isMinor = (age: Int) => age < 18

val (minors, majors) = users.partition(isMinor)

Moving behaviour around instead of moving data around

Page 43: Reactive Web-Applications @ LambdaDays

Transforming dataval addresses = users.filter(_.age > 18) .map(_.address) .sortBy(_.city)

Goal: To build increasingly complex behaviour through a series of transformations / by composing functions

Page 44: Reactive Web-Applications @ LambdaDays

Compositiondef fetchUser(id: Long): Option[User] = ...def fetchCar(id: Long): Option[Car] = ...

val insuranceCost: Option[BigDecimal] = for { user <- fetchUser(42) car <- fetchCar(23)} yield { car.price / 10 - user.age}

Page 45: Reactive Web-Applications @ LambdaDays

Compositiondef fetchUser(id: Long): Future[User] = ...def fetchCar(id: Long): Future[Car] = ...

val insuranceCost: Future[BigDecimal] = for { user <- fetchUser(42) car <- fetchCar(23)} yield { car.price / 10 - user.age}

Page 46: Reactive Web-Applications @ LambdaDays

Compositiondef fetchUser(id: Long): Try[User] = ...def fetchCar(id: Long): Try[Car] = ...

val insuranceCost: Try[BigDecimal] = for { user <- fetchUser(42) car <- fetchCar(23)} yield { car.price / 10 - user.age}

Page 47: Reactive Web-Applications @ LambdaDays

Compositiondef fetchUser(id: Long): [User] = ...def fetchCar(id: Long): [Car] = ...

val insuranceCost: [BigDecimal] = for { user <- (42) car <- (23)} yield { car.price / 10 - user.age}

Page 48: Reactive Web-Applications @ LambdaDays

Composition!OptionFutureTry...

Page 49: Reactive Web-Applications @ LambdaDays

Functional composition

• Option, Future, Try all implement monadic operations

• set of data structures following the same laws

• know one, know them all

• keeping things DRY

• also, it's not that scary

Page 50: Reactive Web-Applications @ LambdaDays

2nd how: Actor model � Akka

Page 51: Reactive Web-Applications @ LambdaDays

History

• 1973 "A Universal Modular Actor Formalism for Artificial Intelligence", Carl Hewitt, Peter Bishop and Richard Steiger

• based on physics (quantum physics and relativistic physics)

• 1986 First release of Erlang (Joe Armstrong)

• 1998 Ericsson reports that the AXD301 switch achieves an availability of 99.9999999%

Page 52: Reactive Web-Applications @ LambdaDays

History

• 2010 First release of Akka (Jonas Bonér)

• inspired by Erlang and the Actor Model

• message-based asynchronous concurrency toolkit

• object-oriented programming done right

Page 53: Reactive Web-Applications @ LambdaDays

History

• 2010 First release of Akka (Jonas Bonér)

• inspired by Erlang and the Actor Model

• message-based asynchronous concurrency toolkit

• object-oriented programming done right

• Akka is also a mountain in Sweden

Page 54: Reactive Web-Applications @ LambdaDays

Actors• lightweight objects

• send and receive messages (mailbox)

• can have children (supervision)

Page 55: Reactive Web-Applications @ LambdaDays
Page 56: Reactive Web-Applications @ LambdaDays
Page 57: Reactive Web-Applications @ LambdaDays
Page 58: Reactive Web-Applications @ LambdaDays

Sending and receiving messagescase object RevelationOfFathership

class Luke extends Actor { def receive = { case RevelationOfFathership => System.err.println("Noooooooooo") }}

Page 59: Reactive Web-Applications @ LambdaDays

Sending and receiving messagescase object RevelationOfFathership

class Luke extends Actor { def receive = { case RevelationOfFathership => System.err.println("Noooooooooo") }}

val luke = ActorSystem.actorOf(Props[Luke])

luke ! RevelationOfFathership

Page 60: Reactive Web-Applications @ LambdaDays

Supervision

class Vader extends Actor {

val troopers: ActorRef = context .actorOf[StromTrooper] .withRouter( RoundRobinRouter(nrOfInstances = 8) )

}

Page 61: Reactive Web-Applications @ LambdaDays

Supervision

class Vader extends Actor {

val troopers: ActorRef = context .actorOf[StromTrooper] .withRouter( RoundRobinRouter(nrOfInstances = 8) )

}

Page 62: Reactive Web-Applications @ LambdaDays

Supervision

class Vader extends Actor {

val troopers: ActorRef = context .actorOf[StromTrooper] .withRouter( RoundRobinRouter(nrOfInstances = 8) )

override def supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 3) { case t: Throwable => log.error("StormTrooper down!", t) Restart }

}

Page 63: Reactive Web-Applications @ LambdaDays

3rd How: Evented servers & statless

architecture � Play

Page 64: Reactive Web-Applications @ LambdaDays

Play history

• MVC framework, inspired by RoR, Django, Symfony

• Zenexity

• first version released in 2009

• version 2.0 released in 2012, core rewritten in Scala

Page 65: Reactive Web-Applications @ LambdaDays

Design Principles• everything is compiled

• non-blocking I/O

• controller actions are functions (request => response)

• "share nothing" => horizontal scalability

Page 66: Reactive Web-Applications @ LambdaDays

Threaded servers

• like a train station with multiple tracks

• station chief decides which trains go on which platform

• if there are more trains than platforms, trains queue up

• if too many trains are queuing up, huge delays occur and passengers go home

Page 67: Reactive Web-Applications @ LambdaDays

Evented servers

• like a waiter in a restaurant

• runs back and forth between tables and the kitchen

• does only small tasks that do not take much time

• one server can each serve many tables at once

Page 68: Reactive Web-Applications @ LambdaDays

Advantages of the evented approach• less threads means less memory

• better CPU utilization (reduced context switching)

• (much) higher throughputs than threaded servers

Page 69: Reactive Web-Applications @ LambdaDays

The Hows1. functional programming (immutability, functions,

composition)

2. actor model

3. evented servers & stateless architecture

4. event-sourcing & reactive streams

Page 70: Reactive Web-Applications @ LambdaDays

Summary

• many-core & distributed systems around the corner and there to stay

• get ready and adopt some of the "new" tools

Page 71: Reactive Web-Applications @ LambdaDays

Thank youhttp://www.manning.com/bernhardt

code ctwlambdad � 41% discount

@elmanu / [email protected]

Questions?