Building Reactive Systems with Akka (in Java 8 or Scala)

176
Building Reactive Systems with Akka Jonas Bonér Typesafe CTO & co-founder Twitter: @jboner

Transcript of Building Reactive Systems with Akka (in Java 8 or Scala)

Page 1: Building Reactive Systems with Akka (in Java 8 or Scala)

Building Reactive Systems

with Akka

Jonas Bonér Typesafe

CTO & co-founder Twitter: @jboner

Page 2: Building Reactive Systems with Akka (in Java 8 or Scala)

The rules of the game have changed

Page 3: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Page 4: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines

Page 5: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Page 6: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors

Page 7: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Page 8: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM

Page 9: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Page 10: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk

Page 11: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Page 12: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks

Page 13: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Page 14: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users

Page 15: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users Lots of concurrent users

Page 16: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users Lots of concurrent users

Small data sets

Page 17: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users Lots of concurrent users

Small data sets Large data sets

Page 18: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users Lots of concurrent users

Small data sets Large data sets

Latency in seconds

Page 19: Building Reactive Systems with Akka (in Java 8 or Scala)

3

Apps in the 60s-90s were written for

Apps today are written for

Single machines Clusters of machines

Single core processors Multicore processors

Expensive RAM Cheap RAM

Expensive disk Cheap disk

Slow networks Fast networks

Few concurrent users Lots of concurrent users

Small data sets Large data sets

Latency in seconds Latency in milliseconds

Page 20: Building Reactive Systems with Akka (in Java 8 or Scala)
Page 21: Building Reactive Systems with Akka (in Java 8 or Scala)

Cost Gravity is at Work

X

Page 22: Building Reactive Systems with Akka (in Java 8 or Scala)

Cost Gravity is at Work

X

Page 23: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive  Applications

Reactive applications share four traits

5

Page 24: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive applications enrich the user experience with low latency response.

Page 25: Building Reactive Systems with Akka (in Java 8 or Scala)

Responsive• Real-time, engaging, rich and collaborative

• Create an open and ongoing dialog with users • More efficient workflow; inspires a feeling of connectedness • Fully Reactive enabling push instead of pull

7

“The move to these technologies is already paying off. Response times are down for processor intensive code–such as image

and PDF generation–by around 75%.”  

Brian Pugh, VP of Engineering, Lucid Software

Page 26: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive applications react to changes in the world around them.

Page 27: Building Reactive Systems with Akka (in Java 8 or Scala)

Message-Driven• Loosely coupled architecture, easier to extend, maintain, evolve

• Asynchronous and non-blocking • Concurrent by design, immutable state • Lower latency and higher throughput

9

“Clearly, the goal is to do these operations concurrently and non-blocking, so that entire blocks of seats or sections are not locked.

We’re able to find and allocate seats under load in less than 20ms without trying very hard to achieve it.”  

Andrew Headrick, Platform Architect, Ticketfly

Page 28: Building Reactive Systems with Akka (in Java 8 or Scala)

Introducing the Actor Model

Page 29: Building Reactive Systems with Akka (in Java 8 or Scala)

11

The Actor Model

Page 30: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

The Actor Model

Page 31: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

The Actor Model

Page 32: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

The Actor Model

Page 33: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

✓ Communication

The Actor Model

Page 34: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

✓ Communication

Supports 3 axioms—when an Actor receives a message it can:

The Actor Model

Page 35: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

✓ Communication

Supports 3 axioms—when an Actor receives a message it can:

1. Create new Actors

The Actor Model

Page 36: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

✓ Communication

Supports 3 axioms—when an Actor receives a message it can:

1. Create new Actors

2. Send messages to Actors it knows

The Actor Model

Page 37: Building Reactive Systems with Akka (in Java 8 or Scala)

11

A computational model that embodies:

✓ Processing

✓ Storage

✓ Communication

Supports 3 axioms—when an Actor receives a message it can:

1. Create new Actors

2. Send messages to Actors it knows

3. Designate how it should handle the next message it receives

The Actor Model

Page 38: Building Reactive Systems with Akka (in Java 8 or Scala)

The essence of an actor from Akka’s perspective

0. DEFINE

1. CREATE

2. SEND

3. BECOME

4. SUPERVISE

12

Page 39: Building Reactive Systems with Akka (in Java 8 or Scala)

public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; }

} !public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }}

0. DEFINE

X

Page 40: Building Reactive Systems with Akka (in Java 8 or Scala)

public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; }

} !public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }}

0. DEFINE

X

Define the message(s) the Actor should be able to respond to

Page 41: Building Reactive Systems with Akka (in Java 8 or Scala)

public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; }

} !public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }}

0. DEFINE

X

Define the message(s) the Actor should be able to respond to

Define the Actor class

Page 42: Building Reactive Systems with Akka (in Java 8 or Scala)

public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; }

} !public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }}

0. DEFINE

X

Define the message(s) the Actor should be able to respond to

Define the Actor classDefine the Actor’s behavior

Page 43: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

1. CREATE

Page 44: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

1. CREATE

Create an Actor system

Page 45: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

1. CREATE

Create an Actor system

Actor configuration

Page 46: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

Give it a name

1. CREATE

Create an Actor system

Actor configuration

Page 47: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

Give it a name

1. CREATE

Create the Actor

Create an Actor system

Actor configuration

Page 48: Building Reactive Systems with Akka (in Java 8 or Scala)

ActorSystem system = ActorSystem.create("MySystem"); !ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");

Give it a name

1. CREATE

Create the ActorYou get an ActorRef back

Create an Actor system

Actor configuration

Page 49: Building Reactive Systems with Akka (in Java 8 or Scala)

0. DEFINE

13

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }

Page 50: Building Reactive Systems with Akka (in Java 8 or Scala)

0. DEFINE

13

Define the message(s) the Actor should be able to respond to

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }

Page 51: Building Reactive Systems with Akka (in Java 8 or Scala)

0. DEFINE

13

Define the message(s) the Actor should be able to respond to

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }

Define the Actor class

Page 52: Building Reactive Systems with Akka (in Java 8 or Scala)

0. DEFINE

13

Define the message(s) the Actor should be able to respond to

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }

Define the Actor class

Define the Actor’s behavior

Page 53: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

1. CREATE

Page 54: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

1. CREATE

Create an Actor system

Page 55: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

1. CREATE

Create an Actor systemActor configuration

Page 56: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

Give it a name

1. CREATE

Create an Actor systemActor configuration

Page 57: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

Give it a name

1. CREATE

Create the Actor

Create an Actor systemActor configuration

Page 58: Building Reactive Systems with Akka (in Java 8 or Scala)

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

Give it a name

1. CREATE

Create the ActorYou get an ActorRef back

Create an Actor systemActor configuration

Page 59: Building Reactive Systems with Akka (in Java 8 or Scala)

Guardian System Actor

Actors can form hierarchies

Page 60: Building Reactive Systems with Akka (in Java 8 or Scala)

Guardian System Actor

system.actorOf(Props.create(Foo.class), “Foo”);

Actors can form hierarchies

Page 61: Building Reactive Systems with Akka (in Java 8 or Scala)

Foo

Guardian System Actor

system.actorOf(Props.create(Foo.class), “Foo”);

Actors can form hierarchies

Page 62: Building Reactive Systems with Akka (in Java 8 or Scala)

Foo

Guardian System Actor

context().actorOf(Props.create(A.class), “A”);

Actors can form hierarchies

Page 63: Building Reactive Systems with Akka (in Java 8 or Scala)

A

Foo

Guardian System Actor

context().actorOf(Props.create(A.class), “A”);

Actors can form hierarchies

Page 64: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

Guardian System Actor

Actors can form hierarchies

Page 65: Building Reactive Systems with Akka (in Java 8 or Scala)

Guardian System Actor

Actors can form hierarchies

Page 66: Building Reactive Systems with Akka (in Java 8 or Scala)

Guardian System Actor

system.actorOf(Props[Foo], “Foo”)

Actors can form hierarchies

Page 67: Building Reactive Systems with Akka (in Java 8 or Scala)

Foo

Guardian System Actor

system.actorOf(Props[Foo], “Foo”)

Actors can form hierarchies

Page 68: Building Reactive Systems with Akka (in Java 8 or Scala)

Foo

Guardian System Actor

context.actorOf(Props[A], “A”)

Actors can form hierarchies

Page 69: Building Reactive Systems with Akka (in Java 8 or Scala)

A

Foo

Guardian System Actor

context.actorOf(Props[A], “A”)

Actors can form hierarchies

Page 70: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

Guardian System Actor

Actors can form hierarchies

Page 71: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

Guardian System Actor

Name resolution—like a file-system

Page 72: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

/Foo

Guardian System Actor

Name resolution—like a file-system

Page 73: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

/Foo

/Foo/A

Guardian System Actor

Name resolution—like a file-system

Page 74: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

/Foo

/Foo/A

/Foo/A/B

Guardian System Actor

Name resolution—like a file-system

Page 75: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

/Foo

/Foo/A

/Foo/A/B

/Foo/A/D

Guardian System Actor

Name resolution—like a file-system

Page 76: Building Reactive Systems with Akka (in Java 8 or Scala)

2. SEND

X

greeter.tell(new Greeting("Charlie Parker”), sender);

Page 77: Building Reactive Systems with Akka (in Java 8 or Scala)

2. SEND

X

Send the message asynchronously

greeter.tell(new Greeting("Charlie Parker”), sender);

Page 78: Building Reactive Systems with Akka (in Java 8 or Scala)

2. SEND

X

Send the message asynchronously

greeter.tell(new Greeting("Charlie Parker”), sender);

Pass in the sender ActorRef

Page 79: Building Reactive Systems with Akka (in Java 8 or Scala)

Bring it together

X

public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; }

} public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); } }} !ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); greeter.tell(new Greeting(“Charlie Parker”));

Page 80: Building Reactive Systems with Akka (in Java 8 or Scala)

2. SEND

17

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker")

Page 81: Building Reactive Systems with Akka (in Java 8 or Scala)

2. SEND

17

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker")

Send the message asynchronously

Page 82: Building Reactive Systems with Akka (in Java 8 or Scala)

Bring it together

18

case class Greeting(who: String) !class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } !val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker")

Page 83: Building Reactive Systems with Akka (in Java 8 or Scala)

DEMO TIMEA simple game of ping pong

Page 84: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Page 85: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

context().become(ReceiveBuilder.

Page 86: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Change the behavior

context().become(ReceiveBuilder.

Page 87: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Change the behavior

context().become(ReceiveBuilder.match(Greeting.class, m -> {

Page 88: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Change the behavior

context().become(ReceiveBuilder.match(Greeting.class, m -> {

println(“Go Away!”);

Page 89: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Change the behavior

context().become(ReceiveBuilder.match(Greeting.class, m -> {

println(“Go Away!”);}).build());

Page 90: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

X

public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }

Change the behavior

context().become(ReceiveBuilder.match(Greeting.class, m -> {

println(“Go Away!”);}).build());

Page 91: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

19

class GreetingActor extends Actor with ActorLogging { def receive = happy ! val happy: Receive = { case Greeting(who) => log.info(s”Hello ${who}") case Angry => context become angry } ! val angry: Receive = { case Greeting(_) => log.info("Go away!") case Happy => context become happy } }

Page 92: Building Reactive Systems with Akka (in Java 8 or Scala)

3. BECOME

19

class GreetingActor extends Actor with ActorLogging { def receive = happy ! val happy: Receive = { case Greeting(who) => log.info(s”Hello ${who}") case Angry => context become angry } ! val angry: Receive = { case Greeting(_) => log.info("Go away!") case Happy => context become happy } }

Redefine the behavior

Page 93: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive applications are architected to handle failure at all levels.

Page 94: Building Reactive Systems with Akka (in Java 8 or Scala)

Resilient• Failure is embraced as a natural state in the app lifecycle

• Resilience is a first-class construct • Failure is detected, isolated, and managed • Applications self heal

21

“The Typesafe Reactive Platform helps us maintain a very aggressive development and deployment cycle, all in a fail-forward manner.

It’s now the default choice for developing all new services.”  

Peter Hausel, VP Engineering, Gawker Media

Page 95: Building Reactive Systems with Akka (in Java 8 or Scala)

Think Vending Machine

Page 96: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Think Vending Machine

Page 97: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Think Vending Machine

Page 98: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Add more coins

Think Vending Machine

Page 99: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Gets coffee

Add more coins

Think Vending Machine

Page 100: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Think Vending Machine

Page 101: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Think Vending Machine

Page 102: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Think Vending Machine

Out of coffee beans error

Page 103: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Think Vending Machine

Out of coffee beans errorWrong

Page 104: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Think Vending Machine

Page 105: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Inserts coins

Out of coffee beans

error

Think Vending Machine

Page 106: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Service Guy

Inserts coins

Out of coffee beans

error

Think Vending Machine

Page 107: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Service Guy

Inserts coins

Out of coffee beans

error

Adds more beans

Think Vending Machine

Page 108: Building Reactive Systems with Akka (in Java 8 or Scala)

Coffee MachineProgrammer

Service Guy

Inserts coins

Gets coffee

Out of coffee beans

error

Adds more beans

Think Vending Machine

Page 109: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Page 110: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Request

Page 111: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Request

Response

Page 112: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Request

Response

Validation Error

Page 113: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Request

Response

Validation Error

Application Error

Page 114: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Supervisor

Request

Response

Validation Error

Application Error

Page 115: Building Reactive Systems with Akka (in Java 8 or Scala)

The Right Way

ServiceClient

Supervisor

Request

Response

Validation Error

Application Error

Manages Failure

Page 116: Building Reactive Systems with Akka (in Java 8 or Scala)
Page 117: Building Reactive Systems with Akka (in Java 8 or Scala)

• Isolate the failure

• Compartmentalize

• Manage failure locally

• Avoid cascading failures

Use Bulkheads

Page 118: Building Reactive Systems with Akka (in Java 8 or Scala)

• Isolate the failure

• Compartmentalize

• Manage failure locally

• Avoid cascading failures

Use Bulkheads

Page 119: Building Reactive Systems with Akka (in Java 8 or Scala)

Enter Supervision

Page 120: Building Reactive Systems with Akka (in Java 8 or Scala)

Enter Supervision

Page 121: Building Reactive Systems with Akka (in Java 8 or Scala)

A

B

BarFoo

C

BE

A

D

C

Automatic and mandatory supervisionSupervisor hierarchies

Page 122: Building Reactive Systems with Akka (in Java 8 or Scala)

4. SUPERVISE

X

class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.create(1, TimeUnit.MINUTES), DeciderBuilder. match(ArithmeticException.class, e -> resume()). match(NullPointerException.class, e -> restart()). matchAny( e -> escalate()). build()); ! @Override public SupervisorStrategy supervisorStrategy() { return strategy; }

Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.

Page 123: Building Reactive Systems with Akka (in Java 8 or Scala)

4. SUPERVISE

X

class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.create(1, TimeUnit.MINUTES), DeciderBuilder. match(ArithmeticException.class, e -> resume()). match(NullPointerException.class, e -> restart()). matchAny( e -> escalate()). build()); ! @Override public SupervisorStrategy supervisorStrategy() { return strategy; } ActorRef worker = context.actorOf( Props.create(Worker.class), "worker"); public void onReceive(Object i) throws Exception { … } }

Page 124: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

X

public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } }

Page 125: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

X

public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } }

Create a child actor

Page 126: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

X

public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } }

Create a child actor

Watch it

Page 127: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

X

public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } }

Create a child actor

Watch it

Handle termination message

Page 128: Building Reactive Systems with Akka (in Java 8 or Scala)

4. SUPERVISE

29

Every single actor has a default supervisor strategy.

Which is usually sufficient. But it can be overridden.

Page 129: Building Reactive Systems with Akka (in Java 8 or Scala)

4. SUPERVISE

29

Every single actor has a default supervisor strategy.

Which is usually sufficient. But it can be overridden.

class Supervisor extends Actor { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: Exception => Escalate } ! val worker = context.actorOf(Props[Worker], name = "worker") ! def receive = {

Page 130: Building Reactive Systems with Akka (in Java 8 or Scala)

4. SUPERVISE

29

class Supervisor extends Actor { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: Exception => Escalate } ! val worker = context.actorOf(Props[Worker], name = "worker") ! def receive = { case n: Int => worker forward n } } !

Page 131: Building Reactive Systems with Akka (in Java 8 or Scala)

Cleanup & (Re)initialization

30

class Worker extends Actor { ... override def preRestart( reason: Throwable, message: Option[Any]) { ... // clean up before restart } override def postRestart(reason: Throwable) { ... // init after restart } }

Page 132: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

31

class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }

Page 133: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

31

class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }

Create a child actor

Page 134: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

31

class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }

Create a child actor

Watch it

Page 135: Building Reactive Systems with Akka (in Java 8 or Scala)

Monitor through Death Watch

31

class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }

Create a child actor

Watch it

Handle termination message

Page 136: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive applications scale up and down to meet demand.

Page 137: Building Reactive Systems with Akka (in Java 8 or Scala)

Elastic• Elasticity and Scalability to embrace the Cloud

• Adaptive Scale on Demand • Clustered servers support joining and leaving of nodes • More cost-efficient utilization of hardware

33

“Our traffic can increase by as much as 100x for 15 minutes each day. Until a couple of years ago, noon was a stressful time.

Nowadays, it’s usually a non-event.”  

Eric Bowman, VP Architecture, Gilt Groupe

Page 138: Building Reactive Systems with Akka (in Java 8 or Scala)

34

Scale OUTScale UP

Page 139: Building Reactive Systems with Akka (in Java 8 or Scala)

34

Essentially the same thing

Page 140: Building Reactive Systems with Akka (in Java 8 or Scala)

35

1. Minimize Contention 2. Maximize Locality of Reference

We need to

Page 141: Building Reactive Systems with Akka (in Java 8 or Scala)

36

Share NOTHING

Design

Page 142: Building Reactive Systems with Akka (in Java 8 or Scala)

Fully event-driven apps are a necessity

X

Amdahl’s Law will hunt you down

Page 143: Building Reactive Systems with Akka (in Java 8 or Scala)

Define a router

X

ActorRef router = context().actorOf( new RoundRobinPool(5).props(Props.create(Worker.class)), “router”)

Page 144: Building Reactive Systems with Akka (in Java 8 or Scala)

Define a router

37

val router = context.actorOf( RoundRobinPool(5).props(Props[Worker])), “router”)

Page 145: Building Reactive Systems with Akka (in Java 8 or Scala)

…or from config

38

akka.actor.deployment { /service/router { router = round-robin-pool resizer { lower-bound = 12 upper-bound = 15 } } }

Page 146: Building Reactive Systems with Akka (in Java 8 or Scala)

Turn on clustering

39

akka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... }    cluster { seed-nodes = [ “akka.tcp://[email protected]:2551", “akka.tcp://[email protected]:2552" ]   auto-down = off } }

Page 147: Building Reactive Systems with Akka (in Java 8 or Scala)

Use clustered routers

40

akka.actor.deployment  {      /service/master  {          router  =  consistent-­‐hashing-­‐pool          nr-­‐of-­‐instances  =  100  !        cluster  {              enabled  =  on              max-nr-of-instances-per-node = 3              allow-­‐local-­‐routees  =  on              use-­‐role  =  compute          }      }  }

Page 148: Building Reactive Systems with Akka (in Java 8 or Scala)

Use clustered routers

40

akka.actor.deployment  {      /service/master  {          router  =  consistent-­‐hashing-­‐pool          nr-­‐of-­‐instances  =  100  !        cluster  {              enabled  =  on              max-nr-of-instances-per-node = 3              allow-­‐local-­‐routees  =  on              use-­‐role  =  compute          }      }  }

Or perhaps use an AdaptiveLoadBalancingPool

Page 149: Building Reactive Systems with Akka (in Java 8 or Scala)

Use clustered pub-sub

41

Page 150: Building Reactive Systems with Akka (in Java 8 or Scala)

Use clustered pub-sub

41

class Subscriber extends Actor { val mediator = DistributedPubSubExtension(context.system).mediator mediator ! Subscribe(“content”, self) def receive = { … } }

Page 151: Building Reactive Systems with Akka (in Java 8 or Scala)

Use clustered pub-sub

41

class Publisher extends Actor { val mediator = DistributedPubSubExtension(context.system).mediator def receive = { case in: String => mediator ! Publish("content", in.toUpperCase) } }

Page 152: Building Reactive Systems with Akka (in Java 8 or Scala)

• Cluster Membership • Cluster Pub/Sub • Cluster Leader • Clustered Singleton • Cluster Roles • Cluster Sharding

42

Other Akka Cluster features

Page 153: Building Reactive Systems with Akka (in Java 8 or Scala)

• Supports two different models:

• Command Sourcing

• Event Sourcing

• Great for implementing

• durable actors

• replication

• CQRS etc.

• Messages persisted to Journal and replayed on restart

43

Use Akka Persistence

Page 154: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

Page 155: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log

Page 156: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

Page 157: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

Page 158: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

Page 159: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation

Page 160: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation events cannot fail

Page 161: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation events cannot fail

allows retroactive changes to the business logic

Page 162: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation events cannot fail

allows retroactive changes to the business logic

fixing the business logic will not affect persisted events

Page 163: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation events cannot fail

allows retroactive changes to the business logic

fixing the business logic will not affect persisted events

naming: represent intent, imperative

Page 164: Building Reactive Systems with Akka (in Java 8 or Scala)

X

Command Sourcing Event Sourcing

write-ahead-log derive events from a command

same behavior during recovery as normal operation

only state-changing behavior during recovery

persisted before validation events cannot fail

allows retroactive changes to the business logic

fixing the business logic will not affect persisted events

naming: represent intent, imperative

naming: things that have completed, verbs in past tense

Page 165: Building Reactive Systems with Akka (in Java 8 or Scala)

Akka  Persistence  Webinar

Domain Events• Things that have completed, facts

• Immutable

• Verbs in past tense • CustomerRelocated • CargoShipped • InvoiceSent

“State transitions are an important part of our problem space and should be modeled within our domain.”  

Greg Young, 2008

Page 166: Building Reactive Systems with Akka (in Java 8 or Scala)

Akka  Persistence  Webinar

Life beyond Distributed Transactions: an Apostate’s Opinion

Position Paper by Pat Helland

“In general, application developers simply do not implement large scalable applications assuming distributed transactions.”  

Pat Helland

http://www-­‐db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf

Page 167: Building Reactive Systems with Akka (in Java 8 or Scala)

Akka  Persistence  Webinar

Consistency boundary

• An Actor is can define an Aggregate Root • Each containing one or more Entities

• Aggregate Root is the Transactional Boundary • Strong consistency within an Aggregate • Eventual consistency between Aggregates

• No limit to scalability

Page 168: Building Reactive Systems with Akka (in Java 8 or Scala)

DEMO TIMEPersist a game of ping pong

Page 169: Building Reactive Systems with Akka (in Java 8 or Scala)
Page 170: Building Reactive Systems with Akka (in Java 8 or Scala)

http://reactivemanifesto.org

Page 171: Building Reactive Systems with Akka (in Java 8 or Scala)

Typesafe Activatorhttp://typesafe.com/platform/getstarted

Page 172: Building Reactive Systems with Akka (in Java 8 or Scala)

48

Typesafe Reactive Platform

• Actors are asynchronous and communicate via message passing

• Supervision and clustering in support of fault tolerance

• Purely asynchronous and non-blocking web frameworks

• No container required, no inherent bottlenecks in session management

• Asynchronous and immutable programming constructs

• Composable abstractions enabling simpler concurrency and parallelism

Page 173: Building Reactive Systems with Akka (in Java 8 or Scala)

Reactive is being adopted acrossa wide range of industries.

Page 174: Building Reactive Systems with Akka (in Java 8 or Scala)

50

Finance Internet/Social Media Mfg/Hardware Government Retail

Page 175: Building Reactive Systems with Akka (in Java 8 or Scala)

Questions?

Page 176: Building Reactive Systems with Akka (in Java 8 or Scala)

©Typesafe 2014 – All Rights Reserved