SLIDE 1 Above the Clouds: Introducing Akka
Jonas Bonér
CTO Typesafe Twitter: @jboner
torsdag 13 oktober 11
SLIDE 2 The problem
It is way too hard to build:
- 1. correct highly concurrent systems
- 2. truly scalable systems
- 3. fault-tolerant systems that self-heals
...using “state-of-the-art” tools
torsdag 13 oktober 11
SLIDE 3 akka
Introducing
torsdag 13 oktober 11
SLIDE 4 Vision
Simpler
Concurrency Scalability Fault-tolerance
torsdag 13 oktober 11
SLIDE 5 Vision
...with a single unified
Programming model Runtime service
torsdag 13 oktober 11
SLIDE 6 Manage system overload
torsdag 13 oktober 11
SLIDE 7 Scale up & Scale out
torsdag 13 oktober 11
SLIDE 8 Replicate and distribute for fault-tolerance
torsdag 13 oktober 11
SLIDE 9 Transparent load balancing
torsdag 13 oktober 11
SLIDE 10 CORE SERVICES
ARCHITECTURE
torsdag 13 oktober 11
SLIDE 11 ADD-ON MODULES
ARCHITECTURE
torsdag 13 oktober 11
SLIDE 12 ARCHITECTURE
CLOUDY AKKA
torsdag 13 oktober 11
SLIDE 13 FINANCE
- Stock trend Analysis & Simulation
- Event-driven messaging systems
BETTING & GAMING
- Massive multiplayer online gaming
- High throughput and transactional
betting
TELECOM
- Streaming media network gateways
SIMULATION
E-COMMERCE
- Social media community sites
SOME EXAMPLES:
WHERE IS AKKA USED?
torsdag 13 oktober 11
SLIDE 14 What is an Actor?
torsdag 13 oktober 11
SLIDE 15 Behavior State Actor
torsdag 13 oktober 11
SLIDE 16 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 17 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 18 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 19 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 20 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 21 Behavior State Actor
torsdag 13 oktober 11
SLIDE 22 Event-driven Thread Behavior State Actor
torsdag 13 oktober 11
SLIDE 23 Akka Actors
torsdag 13 oktober 11
SLIDE 24 case object Tick class Counter extends Actor { var counter = 0 def receive = { case Tick => counter += 1 println(counter) } }
Actors
torsdag 13 oktober 11
SLIDE 25 val counter = actorOf[Counter]
Create Actors
counter is an ActorRef
torsdag 13 oktober 11
SLIDE 26 val counter = actorOf[Counter].start
Start actors
torsdag 13 oktober 11
SLIDE 27 val counter = actorOf[Counter].start counter.stop
Stop actors
torsdag 13 oktober 11
SLIDE 28 counter ! Tick
Send: !
fire-forget
torsdag 13 oktober 11
SLIDE 29 // returns a future val future = actor ? Message future onComplete { f => f.value }
Send: ?
returns the Future directly
torsdag 13 oktober 11
SLIDE 30 Future
val future1, future2, future3 = Future.empty[String] future1.await future2 onComplete { f => ... } future3
- nResult { ... }
- nException { ... }
- nTimeout { ... }
future1 foreach { ... } future1 map { ... } future1 flatMap { ... } future1 filter { ... }
torsdag 13 oktober 11
SLIDE 31 val f0 = Future { ... } Future.firstCompletedOf(futures) Future.reduce(futures)((x, y) => ..) Future.fold(zero)(futures)((x, y) => ...) Future.find { ... } Future.sequence { ... } Future.traverse { ... }
Future
torsdag 13 oktober 11
SLIDE 32 Promise
promise1.completeWithResult(...) promise2.completeWithException(...) promise3.completeWith(promise2)
The write side of the Future
torsdag 13 oktober 11
SLIDE 33 Dataflow
import Future.flow val x, y, z = Promise[Int]() flow { z << x() + y() println("z = " + z()) } flow { x << 40 } flow { y << 2 }
torsdag 13 oktober 11
SLIDE 34 class SomeActor extends Actor { def receive = { case User(name) => // use reply self.reply(“Hi ” + name) } }
Reply
torsdag 13 oktober 11
SLIDE 35 HotSwap
self become { // new body case NewMessage => ... }
torsdag 13 oktober 11
SLIDE 36 HotSwap
self.unbecome()
torsdag 13 oktober 11
SLIDE 37 class MyActor extends Actor { self.dispatcher = Dispatchers .newPinnedDispatcher(self) ... } actor.dispatcher = dispatcher // before started
Set dispatcher
torsdag 13 oktober 11
SLIDE 38 Remote Actors
torsdag 13 oktober 11
SLIDE 39 // use host & port in config Actor.remote.start() Actor.remote.start("localhost", 2552)
Remote Server
Scalable implementation based on NIO (Netty) & Protobuf
torsdag 13 oktober 11
SLIDE 40 import Actor._ remote.register(“service:id”, actorOf[MyService])
Register and manage actor on server client gets “dumb” proxy handle server part
torsdag 13 oktober 11
SLIDE 41 val service = remote.actorFor( “service:id”, “darkstar”, 9999) service ! message
client part
torsdag 13 oktober 11
SLIDE 42 Problem
Deployment (local vs remote) is a dev decision We get a fixed and hard-coded topology Can’t change it dynamically and adaptively
Needs to be a deployment & runtime decision
Remoting in Akka 1.2
torsdag 13 oktober 11
SLIDE 43 Clustered Actors
(in development for upcoming Akka 2.x)
torsdag 13 oktober 11
SLIDE 44 val actor = actorOf[MyActor](“my-service”)
Address
Bind the actor to a virtual address
torsdag 13 oktober 11
SLIDE 45
- Actor address is virtual and decoupled from how it
is deployed
- If no deployment configuration exists then actor is
deployed as local
- The same system can be configured as distributed
without code change (even change at runtime)
- Write as local but deploy as distributed in the
cloud without code change
- Allows runtime to dynamically and adaptively
change topology
Deployment
torsdag 13 oktober 11
SLIDE 46 akka { actor { deployment { my-service { router = "least-cpu" failure-detector = "accrual" clustered { nr-of-instances = 3 replication { storage = "transaction-log" strategy = "write-through" } } } } } }
Deployment configuration
torsdag 13 oktober 11
SLIDE 47
- Subscription-based cluster membership service
- Highly available cluster registry for actors
- Automatic cluster-wide deployment
- Highly available centralized configuration service
- Automatic replication with automatic fail-over upon
node crash
- Transparent and user-configurable load-balancing
- Transparent adaptive cluster rebalancing
- Leader election
- Durable mailboxes - guaranteed delivery
The runtime provides
torsdag 13 oktober 11
SLIDE 48 Akka Node
torsdag 13 oktober 11
SLIDE 49 Akka Node
val ping = actorOf[Ping](“ping”) val pong = actorOf[Pong](“pong”) ping ! Ball(pong)
torsdag 13 oktober 11
SLIDE 50 Akka Node
val ping = actorOf[Ping](“ping”) val pong = actorOf[Pong](“pong”) ping ! Ball(pong)
Ping Pong
torsdag 13 oktober 11
SLIDE 51 Akka Node
Akka Cluster Node Ping Pong
torsdag 13 oktober 11
SLIDE 52 Akka Node
Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong
torsdag 13 oktober 11
SLIDE 53 Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong
torsdag 13 oktober 11
SLIDE 54 akka { actor { deployment { ping {} pong { router = "round-robin" clustered { nr-of-instances = 3 } } } } }
Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong
torsdag 13 oktober 11
SLIDE 55 akka { actor { deployment { ping {} pong { router = "round-robin" clustered { nr-of-instances = 3 } } } } }
Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong
torsdag 13 oktober 11
SLIDE 56 akka { actor { deployment { ping {} pong { router = "round-robin" clustered { nr-of-instances = 3 } } } } }
Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong Pong Pong
torsdag 13 oktober 11
SLIDE 57 akka { actor { deployment { ping {} pong { router = "round-robin" clustered { nr-of-instances = 3 } } } } }
ZooKeeper ZooKeeper ZooKeeper Ensemble Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Akka Cluster Node Ping Pong Pong Pong
torsdag 13 oktober 11
SLIDE 58 Let it crash fault-tolerance
torsdag 13 oktober 11
SLIDE 59 The
Erlang
model
torsdag 13 oktober 11
SLIDE 60
9 nines
torsdag 13 oktober 11
SLIDE 61 ...let’s take a standard OO application
torsdag 13 oktober 11
SLIDE 62 torsdag 13 oktober 11
SLIDE 63 Which components have critically important state and explicit error handling?
torsdag 13 oktober 11
SLIDE 64 torsdag 13 oktober 11
SLIDE 65 Classification of State
- Scratch data
- Static data
- Supplied at boot time
- Supplied by other components
- Dynamic data
- Data possible to recompute
- Input from other sources; data
that is impossible to recompute
torsdag 13 oktober 11
SLIDE 66 Classification of State
- Scratch data
- Static data
- Supplied at boot time
- Supplied by other components
- Dynamic data
- Data possible to recompute
- Input from other sources; data
that is impossible to recompute
torsdag 13 oktober 11
SLIDE 67 Classification of State
- Scratch data
- Static data
- Supplied at boot time
- Supplied by other components
- Dynamic data
- Data possible to recompute
- Input from other sources; data
that is impossible to recompute
Must be protected by any means
torsdag 13 oktober 11
SLIDE 68 Fault-tolerant
Error Kernel
torsdag 13 oktober 11
SLIDE 69 Error Kernel
torsdag 13 oktober 11
SLIDE 70 Error Kernel
torsdag 13 oktober 11
SLIDE 71 Error Kernel
torsdag 13 oktober 11
SLIDE 72 Error Kernel
torsdag 13 oktober 11
SLIDE 73 Error Kernel
torsdag 13 oktober 11
SLIDE 74 Error Kernel
torsdag 13 oktober 11
SLIDE 75 Error Kernel
torsdag 13 oktober 11
SLIDE 76 Error Kernel
torsdag 13 oktober 11
SLIDE 77 Error Kernel
torsdag 13 oktober 11
SLIDE 78 Error Kernel
torsdag 13 oktober 11
SLIDE 79 Error Kernel
torsdag 13 oktober 11
SLIDE 80 Error Kernel
torsdag 13 oktober 11
SLIDE 81 Error Kernel
torsdag 13 oktober 11
SLIDE 82 Error Kernel
torsdag 13 oktober 11
SLIDE 83 Error Kernel
torsdag 13 oktober 11
SLIDE 84 torsdag 13 oktober 11
SLIDE 85 torsdag 13 oktober 11
SLIDE 86 Node 1 Node 2
torsdag 13 oktober 11
SLIDE 87 link(actor) unlink(actor) startLink(actor) spawnLink[MyActor]
Linking
torsdag 13 oktober 11
SLIDE 88 AllForOneStrategy( errors, maxNrOfRetries, withinTimeRange) OneForOneStrategy( errors, maxNrOfRetries, withinTimeRange)
Fault handlers
torsdag 13 oktober 11
SLIDE 89 class ¡Supervisor ¡extends ¡Actor ¡{ ¡ ¡faultHandler ¡= ¡AllForOneStrategy( ¡ ¡ ¡ ¡List(classOf[IllegalStateException]) ¡ ¡ ¡ ¡ ¡5, ¡5000)) ¡ ¡def ¡receive ¡= ¡{ ¡ ¡ ¡ ¡case ¡Register(actor) ¡=> ¡link(actor) ¡ ¡} }
Supervision
torsdag 13 oktober 11
SLIDE 90 class FaultTolerantService extends Actor { ...
- verride def preRestart(reason: Throwable) = {
... // clean up before restart }
- verride def postRestart(reason: Throwable) = {
... // init after restart } }
Manage failure
torsdag 13 oktober 11
SLIDE 91 AMQP Dataflow Security
...and much much more
HTTP Guice scalaz FSM STM Spring Camel OSGi Microkernel
torsdag 13 oktober 11
SLIDE 92 Get it and learn more
http://akka.io
torsdag 13 oktober 11
SLIDE 93
EOF
torsdag 13 oktober 11