Actor-based concurrency in a modern Java Enterprise
Alexander Lukyanchikovgithub.com/sqshq
Agenda
- Overview of concurrency models - Introduc5on to Akka - When to use it - How we use it - Akka with Java and Spring - Pros&Cons, tricky things
- Live demo!
Free lunch is over
Amdahl's Law
S - speedup α - serial part of the algorithm p - number of the processors
Fundamental limita5on of parallel compu5ng
Gunther's Law
Overview of concurrency models
Threads
- the basic unit of concurrency, the closest to hardware - has it's own stack (~ 1Mb) - shared mutable state should be synchronized - sync/locks/context switching are expensive - race condi5ons, starva5on, dead- and live-locks
Overview of concurrency models
- helps to create, manage and u5lize the threads - s5ll have to think about
- thread pool size - task queue size - overflow strategy
Thread pools
Overview of concurrency models
- let to aTach callbacks to the asynchronous task - chaining mul5ple callbacks - control the thread/pool for each task - acceptEither(), thenCombine() and other
helpful methods
Future composiDon
Overview of concurrency models
ReacDve Streams
- define a source and a consumer, library will take care of pushing the data
- transform, combine, split and compose streams - non-blocking back pressure - async error handling
Overview of concurrency models
- lightweight threads, scheduled at the applica5on level - no performance penalty for context switch - thread-like syntax - requires bytecode modifica5on
Fibers
Overview of concurrency models
- extremely lightweigh, independent workers with state - communicate with other actors only by message-passing - can monitor child actors for failure and take measures - that's how OOP was ini5ally thought of
Actor model
Akka- Actor model on JVM - inspired by Erlang
- Scala and Java API - free and open-source
- Scale UP (concurrency) - Scale OUT (Remo5ng + Cluster)
- 50 million msg/sec on single machine - 2.5 million actors per GB of heap
Akka Actor
- Actor is state, behavior, mailbox, child actors and supervision strategy
- On receive it can:- send messages to other actors- create new actors- change the state
- Each one has ActorRef and logical path - Message sending: tell & ask
akka://my-system/user/my-actor/its-child/...
Akka Actor
"Happens before" rules:- the send of the message to an actor happens before
the receive of that message by the same actor - processing of one message happens before processing
of the next message by the same actor.
- Many actors share one thread - Subsequent actor invoca5ons may be on different threads
System design
Pipes & Filters Content-based router
Message endpoint RouDng slipResequencer
ScaLer-gather
Classic Enterprise Integra5on PaTerns to the rescue
ReacDve Messaging PaLerns with the Actor Model: ApplicaDons and IntegraDon in Scala and AkkaVaughn Vernon, 2015
Let it crash!- Defensive programming is an an5-paTern
- Actors should be organized in a hierarchy - Parent actor handle child actors failures
- Using thrown excep5on, parent decides what to do:resume (skip faulty message), restart, stop or escalate the error
- One-for-one strategy - All-for-one strategy
- hooks: preStart(), preRestart(), postStop(), etc
business-logic an error-handling flows are separated
Let it crash!
Dispatchers- Dispatcher is an abstrac5on
over resources (thread pools)
- 3 types:- Dispatcher- PinnedDispatcher- CallingThreadDispatcher
- 2 executors:- thread-pool-executor- fork-join-executor
- min/max number of threadsand throughput are configurableI/OCPU-intensive
default
Bulkhead Pattern
Routers
A router with specified dispatcher:
Router types: - Pool (creates routees as child actors) - Group (sends messages to the specified path) Balancing strategies: - Round robin - Random - Smallest mailbox - Broadcast - ScaTer gather first completed
ReacDve systems
https://www.lightbend.com/reactive-programming-versus-reactive-systemsReacDve programming vs ReacDve Systems
ElasDc Resilent
Message driven
Responsive
Akka Remoteprovides loca=on transparency for peer-to-peer communica5on -
one abstrac=on across all dimensions of scale
Node A
Node B
akka.<protocol>://<actor system name>@<host>:<port>/<actor path>
- Java Serializa5on by default, Kryo/Protobuf/Your-own-serializer supported - SSL/TLS can be used as the remote transport
- Actors can be deployed on remote host - Routers can use remote des5na5ons
Akka Cluster
AP System, based on Amazon's Dynamo paper (Riak DB approach) - Communica5on via Gossip protocol - Vector clocks to reconcile/merge conflicts - Consistent hashing for par55oning - No leader-elec5on process, it is just a role - Failure detector to find unreachable nodes - Seed nodes to start a cluster
provides membership service with no single point of failure
Cluster Singleton Ensures that you have exactly one actor of a certain type running in the cluster
Cluster Sharding Distributes actors across several nodes and supports interac8on with the actorsusing their logical iden8fier without having to care about their physical loca8on
Cluster Client Communica8on from an actor system that is not part of the cluster to actors running somewhere in the cluster
Distributed Publish Subscribe Publish-subscribe and point-to-point messaging between actors in the cluster, sender doesn't have to know on which node the target actor is running
Distributed DataKey-value store like API to share data between nodes in an the cluster
Akka is awesome!
- Simple and powerful way to abstract from low-level concurrency issues
- Ability to build reliable decentralized architecture and scale out with no code changes
- Wonderful documenta5on & community
But.- Need a new mindset
- Code complexity: actors communica5on graph might be trickyFind Usages from IDE won't help here
- Loss of typesafety between actorsyou can live with it, with proper tesAng
- Stacktraces lack meaningwhat was the message? what's the internal state?
- Possible deadlocksbounded mailboxes, synchronizaAon between actors
- Possible OutOfMemoryErrorsunbounded mailboxes under load
Tricky things
- Messages should be immutable
- By default, delivery is not guaranteed*
- Backpressure is importantWork Pulling? Bounded mailbox? Something else?
- Be careful with blocking opera5onsAvoid shared state & synchronizaAon, use separate dispatcher for I/O
* Nobody Needs Reliable Messaging hTps://www.infoq.com/ar5cles/no-reliable-messaging
When to use it- Akka's creators: almost everywhere
- Transac5on processing (online gaming, finance, sta5s5cs)- Service backend (any industry, any app)- Snap-in concurrency/parallelism (any app)- Batch processing (any industry)- Communica5ons hub (telecom, web media, mobile media)- BI/datamining/general purpose crunching
- Common sense: when performance and scalability is crucial- Handle large number of concurrent ac5vi5es- Be easily distributable & scalable over a network of machines
- Well known success stories:Messaging systems, Search indexing, Web-crawling, Sol-real5me analy5cs, Game servers, etc
How we use itCommunica5on hub / Messaging system
- 500k concurrent websocket connec5ons - 8 c4.xlarge (×1.5-2 overprovisioned) - Receive rate per server: ~ 200 messages per second - Send rate per server: ~ 1000 messages per second - Round-trip latency within a system
- 80th pct: 20 ms - 90th pct: 50 ms - 95th pct: 200 ms
- Akka Java API - Spring (DI, websockets, async controllers, etc)
Java
Scala
Scala vs Java API
Java
Scala
Scala vs Java API
Java Scala vs Java API
Scala Scala vs Java API
Scala is nice, nobody doubts
But someDmes business prefers to sDck with Java. Akka Java API is too damn good to argue.
- Actor have a specific lifecycle + it's hidden behind the ActorRefLuckily Akka Extens5ons mechanism allows to use external DI framework
Spring & Akka
- Actor is just a @Prototype bean:
Spring & AkkaAsync Controllers
DEMOLet's get coding, finally!
Robot Control System
Let's keep it simple for the demo
Cluster Aware RouterDistributed pub/sub
Distributeacross mulDple nodes
Distributed data
Scale outthe most overloaded service
Thank you!
hLps://github.com/sqshq/robot-control-system
Top Related