This document discusses 8 anti-patterns to avoid when using Akka. It summarizes each anti-pattern, how it can occur, why it is problematic, and recommends alternatives. The anti-patterns covered include: global mutable state, flat actor hierarchies, too many actor systems, logging incorrectly, being out of touch with hardware, blocking, re-inventing Akka tools, and using Java serialization. For each issue, the presenter provides guidance on better practices to follow instead.
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
8 Akka anti-patterns you'd better be aware of
1. 8 AKKA ANTI-PATTERNS
YOU'D BETTER BE AWARE OF
SCALA ITALY 2017 ROME
MANUEL BERNHARDT / @ELMANU
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
2. WHY THIS TALK?
Tools, of course, can be the subtlest of traps
— Neil Gaiman
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
3. MANUEL.BERNHARDT.IO
> Helping teams to get started with
reactive systems
> Lightbend training partner (Fast
Track to Akka, Advanced Akka, Fast
Track to Scala)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
4. If you want to make enemies, try
to change something.
— Woodrow Wilson
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
6. > it's okay for an actor to have mutable state
> as long as it retains total control over it and is the
only one to see it
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
7. HOW CAN IT HAPPEN?
> reference to mutable state in messages
> closing over mutable state in asynchronous calls
> passing shared mutable state to an actor's
constructor
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
8. WHY IS THIS BAD?
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
13. WHAT TO DO INSTEAD
> use immutable messages for state updates (e.g.
broadcasting for configuration changes)
> use queries for state inquiries (e.g. using the ask
pattern)
> for asynchronous calls, always use the pipe pattern
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
14. The two enemies of human
happiness are pain and boredom.
— Arthur Schopenhauer
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
16. HOW CAN IT HAPPEN?
"Ceci n'est pas une hierarchie" - Magritte, 1928
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
17. IF YOUR ACTOR SYSTEM HAS NO HIERARCHY
YOU ARE MISSING THE POINT.
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
18. WHY IS THIS BAD?
> actor systems are designed to handle failures through
hierarchy
> ergo: no hierarchy, no failure handling
> why then bother to use actors in the first place?
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
19. How exception catch blocks are used in Java projects 1
1
Analysis of Exception Handling Patterns in Java Projects: An Empirical Study (S. Nakshatri, M. Hegde, S. Thandra)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
20. WHAT TO DO INSTEAD?
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
21. WHAT TO DO INSTEAD?
Build hierarchies.
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
22. The mother of excess is not joy
but joylessness.
— Friedrich Nietzsche
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
24. HOW CAN IT HAPPEN?
> eagerly wanting to isolate things
> and not understanding how Akka
works
> (but the intent is good)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
25. WHY IS THIS BAD?
> each actor system has at least one dispatcher backed
by a thread pool
> multiple actor systems = multiple thread pools,
contending for the same resources
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
26. WHAT TO DO INTEAD?
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
27. WHAT TO DO INSTEAD?
Bulkheading with custom dispatchers
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
31. HOW CAN THIS HAPPEN?
> string concatentation
log().debug("Received message: " + msg.toString());
> non-asynchronous logging
> not turning debug logging off in
production settings
> let's get real: logging to files (it is
2017)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
32. WHY IS THIS BAD?
> actor sytems are meant to process millions of
messages per second
> getting logging wrong has a huge performance impact
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
33. WHAT TO DO INSTEAD?
> use Akka's built-in logging facility
> carefully configure the logback appenders, use
asynchronous variants
> use string interpolation: log().debug("Received
message {}", msg);
> use a logging aggregation mechanism (logstash &
friends)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
34. All that we see or seem is but a
dream within a dream.
— Edgar Allan Poe
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
35. ANTI-PATTERN #5BEING OUT OF TOUCH WITH THE HARDWARE
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
36. HOW CAN THIS HAPPEN?
XKCDE 2
2
http://xkcd.com/1764/
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
37. WHY IS THIS A BAD THING?
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
38. WHY IS THIS A BAD THING?
fork-join-executor {
# Min number of threads to cap factor-based parallelism number to
parallelism-min = 2
# Parallelism (threads) ... ceil(available processors * factor)
parallelism-factor = 2.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 10
}
ceil(available processors * factor)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
39. WHY IS THIS BAD?
> suboptimal or simply wrong configuration for the
amount of CPU cores
> costs of context switching
> contending for network
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
40. WHAT TO DO INSTEAD?
> know your hardware and configure accordingly
> beware of virtualization (is the hypervisor lying to
you?)
> run load tests on the same hardware as your target
production system
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
41. "...some men aren't looking for
anything logical, like money. They
can't be bought, bullied, reasoned,
or negotiated with. Some men just
want to watch the world burn."
— Alfred Pennyworth, Batman, The Dark Knight
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
43. HOW CAN THIS HAPPEN?
> calling a synchronous API
> explicitly waiting for the completion of a Future
> using Thread.sleep (don't!)
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
44. WHAT TO DO INSTEAD?
> if you really must (legacy API), use a dedicated
dispatcher optimized for the blocking case (and limited
in resources)
> always use Future in combination with the pipe pattern
> use the akka scheduler if you are waiting for something
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
45. ASK AND PIPE
def receive = {
case ComputePi(precision) =>
val originalSender = sender()
implicit val timeout = Timeout(5.seconds)
val computation: Future[Pi] = piActor ? Compute(precision, originalSender)
val result = computation.recover { case t: AskTimeoutException =>
ComputationTimeout(originalSender, precision)
}
result pipeTo self
case Pi(value, originalSender) =>
originalSender ! PiResult(value)
case ComputationTimeout(originalSender, precision) =>
originalSender ! ComputationFailed(s"Sorry, $precision was too high.")
}
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
46. A man who dares to waste one
hour of time has not discovered
the value of life.
— Charles Darwin
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
54. HOW CAN THIS HAPPEN?
> leaving the default on
> Java serialization over the wire
> Java serialization in Akka Persistance
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
55. WHY IS IT BAD?
> performance penalty!
> poor candidate for protocol evolution - message
evolutions result in older components not able to
process them any longer
> persistance - messages and snapshots can't be
processed any longer after changes
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
56. WHAT TO DO INSTEAD?
> use a proper binary format
> protobuf, avro, thrift
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu
57. THANK YOU
> Questions, comments, feedback?
> Contact me at manuel@bernhardt.io / @elmanu
> Check out my blog at https://manuel.bernhardt.io
Scala Italy 2017 Rome - manuel.bernhardt.io - @elmanu