Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Akka in action

Akka in action

Akka in action presentation used at Xebicon 2013

Raymond Roestenburg

August 13, 2013
Tweet

More Decks by Raymond Roestenburg

Other Decks in Programming

Transcript

  1. manning.com/roestenburg 12mp25 for 42% Off! Early Akka adopter (v0.7, 2010)

    Akka Committer (akka-camel in 2.x) Co-author of Akka in Action
  2. “The free lunch is over” / TANSTAAFL Herb Sutter 2005

    http://www.gotw.ca/publications/concurrency-ddj.htm Number of transistors Clock Speed
  3. Can’t I just.. Parallelize that Sh*t™? Put that in a

    box! Something like this? Parallel Version 9 Hey Oracle don’t sue me, of course it’s fake
  4. Nope. Parallelize that Sh*t™ Not every algorithm can be parallelized

    Dynamic coordination (concurrent) Amdahl’s Law Sequential fraction determines max speedup
  5. Threads? Shared (mutable) state + locks Require synchronization Diminishing returns**

    Which primitives to use? Difficult to predict & maintain Deadlock Livelock Thread starvation Race condition *Using threads directly is meant here **Performance improvement degrades with more threads than cores.
  6. Why Async? Less latency. Ser Service A Service B Service

    C 4 sec 6 sec 3 sec Sync takes 13 seconds Async takes max 6 seconds Asynchronous ‘first completed response’ is easy to do
  7. 1. The world is concurrent 2. Things in the world

    don't share data 3. Things communicate with messages 4. Things fail Joe Armstrong (creator of Erlang)
  8. Scale Up and Out Concurrent Distributed Many Nodes Many Threads

    Akka A uniform model for both up and out, embraces concurrency and failure Maximize the use of cores _and_ nodes. Concurrent (more Cores) Distributed (more Nodes)
  9. Scale Up Processes (even less**) Actors (2.7 million / 1GB)

    Threads (4096 / 1GB) Actors are small* * Disclaimer: text is not shown to scale, actors are way smaller.. ** Especially JVM processes
  10. Mailbox Actor Instance ActorRef Mailbox Processes Messages asynchronously* Invokes Actor

    Instance with message *The Mailbox runs on a Dispatcher that abstracts threading
  11. Actor Instance Crashed Actor Instance Mailbox An Actor Instance crashes

    instead of handling Exceptions. A Supervisor decides it’s fate. ActorRef Restart / Resume / Stop / Escalate New Actor Instance
  12. ActorRef Actor Instance Mailbox The ActorRef always points 1 on

    1 to the ‘same’ Actor instance. (Alive or Restarted) ActorRef Actor Instance
  13. ActorRef Dead Actor Instance Mailbox The ActorRef points to deadletters

    ActorRef when the actor is dead (terminated). ActorRef deadletters
  14. msg msg Immutable messages msg Location Transparency msg Serialized messages

    Actor System Actor System Actor System Actor systems Event
  15. Immutable messages msg msg app@node2 app@node1 app@node3 “app” clustered actor

    system On three nodes Clustered actor system msg msg
  16. “GoTicks.com” Build a REST API PUT /events { “event” :

    “RHCP”, “nrOfTickets”: 300 } GET /ticket/RHCP Response: { “event”: “RHCP”, “nr”: 1 } GET /events Response: [ { “event”: “RHCP”, “nrOfTickets”: 299 } ]
  17. GoTicks.com BoxOffice REST Spray-can BoxOffice Creates Events Creates TicketSeller One

    for every Event Partition / shard per event Many sharding strategies possible
  18. RestApi Ticket Seller Ticket Seller BoxOffice Clustered GoTicks.com Ticket Seller

    Ticket Seller BoxOffice Consistent Hashing Consistent Hashing
  19. Inside Main… val system = new ActorSystem(“goticks”) val api =

    system.actorOf( Props[RestInterface], “httpInterface”) … CREATE RestInterface ActorSystem(“goticks”) Top Level Actor ActorSystem(“goticks”) REST Interface
  20. Inside Main… val system = new ActorSystem(“goticks”) val api =

    system.actorOf( Props[RestInterface], “httpInterface”) … CREATE RestInterface ActorSystem(“goticks”) Factory/Creator/ Immutable Configuration object ActorSystem(“goticks”) REST Interface
  21. Inside Main… val system = new ActorSystem(“goticks”) val api =

    system.actorOf( Props[RestInterface], “httpInterface”) … CREATE RestInterface ActorSystem(“goticks”) ActorRef to the Actor ActorSystem(“goticks”) REST Interface
  22. Inside BoxOffice… val child = context.actorOf( Props[TicketSeller], eventName ) 1.

    CREATE TicketSeller ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice TicketSeller Child of BoxOffice Actor
  23. Inside BoxOffice… val child = context.actorOf( Props[TicketSeller], eventName ) 1.

    CREATE TicketSeller ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice TicketSeller Ticket sellers are named by event
  24. Receiving messages class BoxOffice extends Actor { def receive =

    { case TicketRequest(name) => … case GetEvents => … case event: Event => … } } Pattern Matching On Messages
  25. Receiving messages class TicketSeller extends Actor { def receive =

    soldOut def soldOut:Receive = { case Tickets(newTickets) => .. //store new tickets become(selling) } def selling:Receive = { case BuyTicket(name) => … } } Partial Function 3. BECOME: You can change th behavior at every msg
  26. Create Event ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice Event(“RHCP”, 250) {

    event: “RHCP” nrOfTickets: 250} Inside RestInterface… (receives JSON, unmarshall to event) boxOffice ! event
  27. Create Event ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice Event(“RHCP”, 250) {

    event: “RHCP” nrOfTickets: 250} Inside RestInterface… (receives JSON, unmarshall to event) boxOffice ! event Bang Operator ‘Tell’ ‘One-way’
  28. ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice Event(“RHCP”, 250) { event: “RHCP”

    nrOfTickets: 250} Inside RestInterface… boxOffice ! event Receiver can respond to ‘sender’ Send Event To BoxOffice
  29. ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice { event: “RHCP” nrOfTickets: 250}

    BuyTicket TicketSeller Inside BoxOffice… ticketSeller forward BuyTicket Get a Ticket Forward keeps sender (RestInterface) TicketRequest(“RHCP”)
  30. ActorSystem(“goticks”) ActorSystem(“goticks”) REST Interface BoxOffice { event: “RHCP”, nr :1}

    TicketSeller Inside TicketSeller… sender ! ticket Respond to original sender BuyTicket Ticket(“RHCP”, 1)
  31. Send Thread Consumer Consumer Consumer Thread Thread Thread Service A

    Thread 2 fails Handle every possible error inside Thread 2, never fail? Not completely under your control.
  32. Send Thread Consumer Consumer Consumer Thread Thread Thread Service A

    Thread 2 fails Restart / Stop? Monitor? Handle errors across all subscriptions?
  33. 4. Supervise* val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 5, withinTimeRange =

    1 minute) { case _: Exception => Restart } Restart, Resume, Escalate, Stop,