Akka messaging mechanisms by example

2019-01-17 09:10发布

问题:

I have a fair amount of Apache Camel (routing/mediation/orchestation engine; lightweight ESB) experience and am racking my brain trying to understand the difference between Akka:

  • Dispatchers (Dispatcher, PinnedDispatcher, CallingThreadDispatcher)
  • Routers
  • Pools
  • Groups
  • Event Buses

According to the docs:

Dispatchers are:

...is what makes Akka Actors “tick”, it is the engine of the machine so to speak.

But that doesn't really explain what a dispatcher is or what it's relationship to an actor is.

Routers are:

Messages can be sent via a router to efficiently route them to destination actors, known as its routees. A Router can be used inside or outside of an actor, and you can manage the routees yourselves or use a self contained router actor with configuration capabilities. But it sounds an awful lot like a dispatcher.

Pools are:

[A type of] router [that] creates routees as child actors and removes them from the router if they terminate.

Groups are:

[A type of] actor [where routees] are created externally to the router and the router sends messages to the specified path using actor selection, without watching for termination.

Event Buses are:

...a way to send messages to groups of actors

This sounds just like dispatchers and routers.

So my main concerns are:

  • What is the difference between dispatchers, routers and event buses, and when to use each?
  • When to use pool vs group?

回答1:

A dispatcher is basically a thread-pool. Akka uses dispatcher for multiple things (like enqueueing messages in the right mailbox or pick up a message from an actor mailbox and process it). Every time one of these actions need to be performed a thread from the thread-pool is selected and used for it. Akka comes by default with a default-dispatcher with the config you can find here in reference.conf searching for default-dispatcher. You are already using the default-dispatcher but you can define a different dispatcher to ensure you have a reserved thread-pool for other purposes (for example for the netty threads when using akka-remote or akka-cluster).

A router in Akka is an actor that uses some kind of routing logic to route messages to a list of routees. There are many types of router depending on the logic: Broadcast, Balancing, RoundRobin... you can find all of them in the akka docs. The routees of the router can be a pool or a group. One of the most popular use cases of routers is to vertically scale your app which means maximize the use of all the CPU available in your system (using multiple threads at the same time).

A pool means that the routees are being created on-demand for a given type. For example you may want a RandomPool of MyFancyActor with 3 instances. Akka will create three actors of MyFancyActor and a fourth one that will be the actual router. Every time the router actor gets a message will be forwarding the message to one of the 3 MyFancyActor actors. A pool takes care of restarting actors and watch their lifecycle to ensure you have n number of instances running.

A group means that the routees are being created before you are defining the router. Once you are defining your router you will need to pass a list of your routees actor that you previously created. A group will not monitor the lifecycle of your actors and you will need to do this yourself.

Event buses are channels where you can subscribe for a particular type of message with an actor. If there is a message of that particular type, you actor will get it. This is used for some Akka internals like subscribing to DeadLetters when a message is unable to reach its destination or events regarding the formation of a cluster (in akka-cluster). You will use this to be aware of events happening in your ActorSystem.