first glance at akka 2.0

Post on 06-May-2015

6.656 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

This presentation has been made at the 4th meetup of Belarusian Scala Enthusiasts by @remeniuk

TRANSCRIPT

Akka 2.0: towards new heights @remeniuk

emilypolar@flickr

Location Transparency

You’re doing your regular coding job for a local

environment, and get ability to run your system in a

distributed environment any time for free.

RMI, EJB, CORBA, SOAP,

XML-RPC, Thrift

RMI, EJB, CORBA, SOAP,

XML-RPC, Thrift

are easy, but ultimately

flawed!

Fail under network

partitioning and partial

failure...

RMI, EJB, CORBA, SOAP,

XML-RPC

are easy, but ultimately

flawed!

Fail under network

partitioning and partial

failure...

It’s time for RPC to retire.

Steve Vinovsky

RMI, EJB, CORBA, SOAP,

XML-RPC

are easy, but ultimately

flawed!

Fail under network

partitioning and partial

failure...

Akka*

Simple toolkit for building

distributed, scalable,

fault-tolerant systems

• actors / transactors

• supervisors

• routing and dispatching

• STM for better shared

stated concurrency

• much more…

class HelloWorldActor extends Actor {

def receive = {

case msg => self reply (msg + " World")

}

}

val myActor = actorOf[HelloWorldActor].start()

val result = myActor !! “message”

LocalActorRef

Dispatcher stuffs actor[-s] with messages

class ActorA extends Actor {

self.dispatcher = someDispatcher

...

}

class ActorB extends Actor {

self.dispatcher = someDispatcher

...

}

Actor Registry knows about all the local

actors

registry.actorFor(id)

registry.actorFor(uuid)

registry.actorsFor(classOf[...])

etc.

making actor accessible remotely

remote.start("localhost", 9999).register(

"hello-service", actorOf[HelloWorldActor])

val actor = remote.actorFor(

"hello-service", "localhost", 9999)

val result = actor !! "Hello"

RemoteActorRef

Moreover, there could be a pool of

actors behind the ActorRef

class MyLoadBalancer extends Actor with LoadBalancer {

val pinger = actorOf(new Actor {

def receive = { case x => println("Pinger: " + x) } }).start()

val ponger = actorOf(new Actor {

def receive = { case x => println("Ponger: " + x) } }).start()

val seq = new CyclicIterator[ActorRef](List(pinger,ponger))

}

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

Fault tolerance

Groups of linked, supervised actors define subsystems:

those actors crash and restart together

val supervisor = Supervisor(

SupervisorConfig(

AllForOneStrategy(List(classOf[Exception]), 3, 1000),

Supervise(actorOf[MyActor1], Permanent) ::

Supervise(actorOf[MyActor2], Permanent) ::

Nil))

actor1.link(actor2)

supervisor.link(actor2)

Akka 2.0

In Akka 2.0 there’re no local vs.

remote actors anymore. All the

actors are distributed (clustered, routed)

the new level of transparency

brand new akka-cluster

in Soviet Russia by default, all the actors are local

but when you pass a config

cluster magic starts to happen

cluster magic

• actors migration

• actors replication

• cluster-wide routing

• adaptive load balancing

• distributed actor registry

• leader election

• much more…

New important concepts:

• actor address

• deployment config

[behind the scenes]

actor clustering

Distributed Registry

get deployment config

is scope

local?

add to local actor registry

store serilized actor

factory in ZooKeepercreate

actor

create actor on

node

ClusteredActorRef / RoutedActorRef

LocalActorRef

ZooKeeper is used for storing

cluster configs, serialized actor

factories, metrics, etc.

akka.enabled-modules = ["cluster"]

akka.event-handler-level = "WARNING"

akka.actor.deployment.service-hello.router = "round-robin"

akka.actor.deployment.service-hello.clustered.replication-factor = 2

akka.actor.deployment.service-hello.clustered.preferred-nodes =

["node:node1","node:node3"]

node.start()

helloActor = actorOf[HelloWorld]("service-hello“)

Using clustered actor

[Akka 1.x] PROBLEM: synchronization of

registries in a distributed network?

POSSIBLE SOLUTION: https://github.com/remeniuk/akka-easyscale

Distributed Registry

Node A

node.store(“my-actor", classOf[MyActor], serializerFor(classOf[MyActor]))

Node B

node.use(“my-actor")

Actor Props

actorOf(Props[TestActor]

.withDispatcher(new PinnedDispatcher())

.withFaultHandler(

OneForOneStrategy(List(classOf[Exception]), 5, 1000))

actorOf(Props(self ⇒ {

case “hello" ⇒ self tryReply “hello!"

})

Composable Futures

!! *HINT: (actor ? message).get

Composable Futures

val future1 = for {

a <- (actor ? message1).mapTo[String]

b <- (actor ? message2).mapTo[String]

} yield a + b

val future2 = (actor ? Message3).map(_.toString)

val future3 = Futures.find[String](_.isEmpty)(

Seq(future1, future2))

BONUS: multi-jvm testing with

scalatest in specs2

https://github.com/typesafehub/sbt-multi-jvm

https://github.com/jboner/akka/tree/master/akk

a-cluster/src/multi-jvm

https://github.com/remeniuk/sbt-multi-jvm

GO AND TRY IT!

> git clone https://github.com/jboner/akka

> sbt

top related