Reactive applications using Akka

6,593 views
6,437 views

Published on

Basic intro to reactive applications concepts and a crash course on some of the tools Akka and some other providers give use

Published in: Technology, Business
0 Comments
32 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,593
On SlideShare
0
From Embeds
0
Number of Embeds
113
Actions
Shares
0
Downloads
190
Comments
0
Likes
32
Embeds 0
No embeds

No notes for slide

Reactive applications using Akka

  1. 1. Miguel Ángel Pastor Olivar Reactive Applications Building concurrent and distributed apps using Akka miguelinlas3@gmail.com - Liferay Inc and MadridJUG @miguelinlas3 Saturday, October 19, 13
  2. 2. About me Writing software for the Liferay platform team Phd student? on distributed and cloud systems Scala enthusiast Twitter: @miguelinlas3 Saturday, October 19, 13
  3. 3. Agenda Reactive apps: do we really need them? Crash course on basic Akka concepts Old known problems A quick look into newer (and more fun tools) Saturday, October 19, 13
  4. 4. Reactive applications Applications has become extremely demanding New kind of systems Event driven, scalable , resilient, responsive This is what Reactive Applications are all about Saturday, October 19, 13
  5. 5. Reactive applications: definitions Blocking Caller blocked. Wait for the results Non blocking Caller not blocked. Need to pool Asynchronous Caller not blocked. Select, epoll, signals Event driven Message flowing through the system Saturday, October 19, 13
  6. 6. Basic pillars Saturday, October 19, 13
  7. 7. Basic pillars Event Driven Saturday, October 19, 13
  8. 8. Basic pillars Event Driven Resilient Saturday, October 19, 13
  9. 9. Basic pillars Event Driven Resilient Saturday, October 19, 13 Scalable
  10. 10. Basic pillars Event Driven Resilient Scalable Responsive Saturday, October 19, 13
  11. 11. Going event driven Old known problems, The actor model Saturday, October 19, 13
  12. 12. Going Event Driven Saturday, October 19, 13
  13. 13. Going Event Driven Shared Memory Saturday, October 19, 13
  14. 14. Going Event Driven Shared Memory Saturday, October 19, 13
  15. 15. Going Event Driven Thread 1 Shared Memory Saturday, October 19, 13
  16. 16. Going Event Driven Thread 1 Thread 2 Shared Memory Saturday, October 19, 13
  17. 17. Going Event Driven Thread 1 Thread 2 Shared Memory Saturday, October 19, 13
  18. 18. Going Event Driven Thread 1 Thread 2 Shared Memory Saturday, October 19, 13
  19. 19. Going Event Driven Thread 1 Thread 2 R/W Shared Memory Saturday, October 19, 13
  20. 20. Going Event Driven Thread 1 Thread 2 R/W R/W Shared Memory Saturday, October 19, 13
  21. 21. Going Event Driven Thread 1 Thread 2 R/W R/W Shared Memory Saturday, October 19, 13 AVOID IT!!
  22. 22. Going event driven: problems with locks Saturday, October 19, 13
  23. 23. Going event driven: problems with locks Composition Saturday, October 19, 13
  24. 24. Going event driven: problems with locks Composition Locks don´t compose Saturday, October 19, 13
  25. 25. Going event driven: problems with locks Composition Locks don´t compose Saturday, October 19, 13 Granularity
  26. 26. Going event driven: problems with locks Composition Locks don´t compose Have I taken too few locks? Too many? Saturday, October 19, 13 Granularity
  27. 27. Going event driven: problems with locks Composition Locks don´t compose Have I taken too few locks? Too many? Encapsulation Saturday, October 19, 13 Granularity
  28. 28. Going event driven: problems with locks Composition Locks don´t compose Have I taken too few locks? Too many? Encapsulation Breaking abstractions Saturday, October 19, 13 Granularity
  29. 29. Going event driven: problems with locks Composition Locks don´t compose Granularity Have I taken too few locks? Too many? Encapsulation Breaking abstractions Saturday, October 19, 13 Correctness
  30. 30. Going event driven: problems with locks Composition Locks don´t compose Granularity Have I taken too few locks? Too many? Encapsulation Breaking abstractions Correctness Have I taken the correct lock? Saturday, October 19, 13
  31. 31. Going event driven: problems with locks Composition Locks don´t compose Granularity Have I taken too few locks? Too many? Encapsulation Breaking abstractions Ordering Saturday, October 19, 13 Correctness Have I taken the correct lock?
  32. 32. Going event driven: problems with locks Composition Locks don´t compose Granularity Have I taken too few locks? Too many? Encapsulation Breaking abstractions Ordering Saturday, October 19, 13 Have I used the correct order? Correctness Have I taken the correct lock?
  33. 33. Going event driven: designing your system Asynchronous message/event passing Workflow of the events through your system Benefits: Better throughput Lower latencies Loosely coupled solutions Saturday, October 19, 13
  34. 34. Going event driven: Amdahl’s law Saturday, October 19, 13
  35. 35. Going event driven: the actor model Fundamental unit of computation that embodies: • Processing • Storage • Communication Three axioms. When an Actor receives a message it can: • Create new Actors • Send messages to Actors it knows • Designate how it should handle the next message it receives Carl Hewitt Saturday, October 19, 13
  36. 36. Going event driven: the actor model Saturday, October 19, 13
  37. 37. Going event driven: the actor model Saturday, October 19, 13
  38. 38. Going event driven: the actor model Saturday, October 19, 13
  39. 39. Going event driven: the actor model Zero sharing Isolated, lightweight event based processes Communication through asynchronous message passing Location transparent Built-in supervision Saturday, October 19, 13
  40. 40. Actor model: Define a new actor public class MetricsProcessorActor extends UntypedActor { public void onReceive(Object message) { if (message instanceof JVMMetric) { JVMMetric jvmMetric = (JVMMetric)message; } } } _dataStore.save(jvmMetric); private DataStore _dataStore = new LogDataStore(); Saturday, October 19, 13
  41. 41. Actor model: Creating an actor ActorSystem _agentSystem = ActorSystem.create("AgentSystem"); ActorRef metricsActor = _agentSystem.actorOf( new Props(new UntypedActorFactory() { @Override public Actor create() { return new MetricsActor(metricsActor); } }), "metricsActor"); Saturday, October 19, 13
  42. 42. Actor model: Getting a reference ActorSystem _agentSystem = ActorSystem.create("AgentSystem"); ActorRef handshakeActor = _agentSystem.actorFor( "akka://MonitoringServiceSystem@localhost:5557/user/ handshakeActor"); Saturday, October 19, 13
  43. 43. Actor model: Sending a message metricsActor.tell( new JVMMessage("JVM-MemoryUsage", new Date().getTime())); Saturday, October 19, 13
  44. 44. Actor model: Replying to a message public class HandshakeActor extends UntypedActor { public void onReceive(Object message) { if (message instanceof AuthMessage) { AuthMessage authMessage = (AuthMessage)message; if (authMessage.getUser() == "migue" && authMessage.getCredentials() == "migue") getSender().tell("ok"); else getSender().tell("fail"); } } } else throw new IllegalStateException("Unable to handle " + message); Saturday, October 19, 13
  45. 45. Actor model: Switching implementation public class MetricsProcessorActor extends UntypedActor { public void onReceive(Object message) { if (message instanceof SwappingMessage) { getContext().become(altPersistence, false) } } { }; } Procedure<Object> altPersistence = new Procedure<Object>() @Override public void apply(Object message) { altDatastore.save(message); } DataStore altDatastore = new AltDataStore(); private DataStore _dataStore = new LogDataStore(); Saturday, October 19, 13
  46. 46. Actor model: Routing final ActorSystem monitoringServiceSystem = ActorSystem.create("MonitoringServiceSystem"); ActorRef metricsActor = monitoringServiceSystem.actorOf( new Props(MetricsProcessorActor.class).withRouter( new RoundRobinRouter(100), "metricsActor"); } Dealing with routers does not change our code metricsActor.tell( new JVMMessage("JVM-MemoryUsage", new Date().getTime())); Saturday, October 19, 13
  47. 47. Actor model: Configuring a router akka { actor { deployment { /metricsActor { router = round-robin nr-of-instances = 100 } } } } Saturday, October 19, 13
  48. 48. Going scalable Distributed computing, The actor model Saturday, October 19, 13
  49. 49. Going scalable: scalability I really do have an scalability problem ... if my system is fast for a single user but slow when the system is under heavy load Saturday, October 19, 13
  50. 50. Going scalable: transparent distributed computing Distributed shared mutable state Distributed objects Distributed transactions Saturday, October 19, 13
  51. 51. Going scalable: transparent distributed computing Synchronous method dispatching across the network is a bad idea Ignores partial failures Raises Latency General scalability and DC concerns Saturday, October 19, 13
  52. 52. Going scalable: transparent distributed computing EMBRACE THE NETWORK!! Saturday, October 19, 13
  53. 53. Going scalable: remote actors akka { actor { deployment { /metricsActor { remote = "akka://monitorSystem@name:5557" } } } } No changes are required in our existing code!! final ActorSystem monitoringServiceSystem = ActorSystem.create("MonitoringServiceSystem"); ActorRef metricsActor = monitoringServiceSystem.actorOf( new Props(MetricsProcessorActor.class), "metricsActor"); Saturday, October 19, 13
  54. 54. Going resilient Error handling Saturday, October 19, 13
  55. 55. Going resilient: common problems Single thread of control Thread blows up --> you are screwed Error handling within single thread Errors don´t get propagated Defensive programming Tangled within business logic Scattered along all our codebase Saturday, October 19, 13
  56. 56. Going resilient: actor topology and supervision System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  57. 57. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  58. 58. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  59. 59. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  60. 60. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  61. 61. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  62. 62. Supervision strategies: One for one System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  63. 63. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  64. 64. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  65. 65. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  66. 66. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  67. 67. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  68. 68. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  69. 69. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  70. 70. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  71. 71. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  72. 72. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 /B1/B2/B7 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 B4 /B1/B2/B4
  73. 73. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  74. 74. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  75. 75. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  76. 76. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  77. 77. Supervision strategies: One for all System /B1 /A1 B1 A1 /B1/B3 /A1/A2 /B1/B2 B3 B2 A2 /A1/A3 A3 B7 B5 /A1/A2/A4 A4 B6 B4 /B1/B3/B5 /B1/B2/B6 Saturday, October 19, 13 /B1/B2/B7 /B1/B2/B4
  78. 78. Going resilient: configure supervision final SupervisorStrategy supervisorStrategy = new OneForOneStrategy( 3, Duration.create(1, TimeUnit.MINUTES), new Class<?>[] {Exception.class}); _metricsActor = _cloudServiceSystem.actorOf( new Props(MetricsProcessorActor.class). withRouter( new RoundRobinRouter(100). withSupervisorStrategy( supervisorStrategy)), "metricsActor"); Supervision strategies are pluggable and you can develop and configure your own Saturday, October 19, 13
  79. 79. More tools We deserve better and more fun tools Saturday, October 19, 13
  80. 80. More tools: futures •Spawn concurrent computations •Write once - Read many •Freely sharable •Non-blocking composition •Composable (monadic operations) •Managing failure Saturday, October 19, 13
  81. 81. More tools: futures val f: Future[List[String]] = future { session.getRecentPosts } // handle both cases: Success and Failure f onComplete { case Success(posts) => for (post <- posts) println(post) case Failure(t) => println("An error has occured: " + t.getMessage) } // only handle Success f onSuccess { case posts => for (post <- posts) println(post) } // only handle Failure f onFailure { case t => println("An error has occured: " + t.getMessage) } Saturday, October 19, 13
  82. 82. More tools: agents •Reactive memory cells •Send update function to an agent •Reads are “free” •Composable •Originally in Clojure, borrowed by Akka Saturday, October 19, 13
  83. 83. More tools: agents // declare the agent val counter = Agent(0) // send the function: enqueued the change counter send { _ + 1} // long running or blocking operations implicit val ec = defineSomeExecutionContext() agent sendOff blockingOperation // read the agent’ s value val agentValue = counter.value Saturday, October 19, 13
  84. 84. More tools: software transactional memory Sometimes we will deal with shared state Heap + Stack: transactional dataset: Begin, commit, rollback Retry on collision Rollback on abort Transaction composability Saturday, October 19, 13
  85. 85. More tools: reactive extensions •Futures + Stream concept •Composables •Async and event based •Push collections •JVM available through the RxJava project Saturday, October 19, 13
  86. 86. More tools: reactive extensions def simpleComposition() { customObservableNonBlocking() .skip(10) .take(5) .map({ stringValue -> return stringValue + "_transformed"}) .subscribe({ println "nextElement => " + it}) } // we should an output like this nextElement nextElement nextElement nextElement nextElement Saturday, October 19, 13 => => => => => foo_10_transformed foo_11_transformed foo_12_transformed foo_13_transformed foo_14_transformed
  87. 87. More tools: reactive extensions def Observable<T> getData(int id) { if(availableInMemory) { return Observable.create({ observer -> observer.onNext(valueFromMemory); observer.onCompleted(); }) } else { return Observable.create({ observer -> executor.submit({ try { T value = getValueFromRemoteService(id); observer.onNext(value); observer.onCompleted(); }catch(Exception e) { observer.onError(e); } }) }); } } Saturday, October 19, 13
  88. 88. Useful approaches Where should I use each tool? Saturday, October 19, 13
  89. 89. Layers of complexity Declarative & immutable core Logic or functional programming Futures and/or dataflow Non-determinism when needed Actors, Agents or Rx Shared mutability Protected by Software Transactional Memory Finally, only if it is really needed Locks and explicit threads Saturday, October 19, 13
  90. 90. Takeways A quick summary Saturday, October 19, 13
  91. 91. Takeaways Go reactive Avoid locking (share nothing, lock free algs) Already in the JVM? Akka could be good choice Distributed systems are hard Use the correct level of abstraction And remember ... Saturday, October 19, 13
  92. 92. Takeaways hammer When all you have is a everything looks like a nail. Choose the right tool for your job! Saturday, October 19, 13
  93. 93. Questions? And let’s hope answers Saturday, October 19, 13
  94. 94. References Interesting resources Saturday, October 19, 13
  95. 95. References: slides, talks and books High Performance Networking in the JVM by Eric Onnen Going reactive talk by Jonas Bonér Introducing Akka by Jonas Bonér The future I was promised by Viktor Klang Real world Akka recipes by Björn Antonsson et all Saturday, October 19, 13
  96. 96. References: slides, talks and books Programming Concurrency in the JVM: Mastering synchronization, STM and Actors by Venkat Subramaniam Systems than run forever Self-heal by Joe Amstrong The art of multiprocessor programming, Revised Reprint by Maurice Herlihy Reactive Manifesto Saturday, October 19, 13
  97. 97. References: frameworks and toolkits Erlang Akka Toolkit Scala language Vert.x Clojure language GPars Saturday, October 19, 13
  98. 98. References: frameworks and toolkits Cloud Haskell NodeJS Netty IO Finagle Saturday, October 19, 13

×