官术网_书友最值得收藏!

Mailbox types in Akka

Like dispatchers, mailboxes are central to the functionality within Akka's actor system. Every actor instance has a mailbox (be it isolated or shared) that acts as a queue, feeding the work that the actor does. The mailbox always processes one message at a time, serially, which is a guarantee that enables the safe concurrent programming with actors. Since there are a few different flavors of mailboxes, it makes sense to discuss them briefly here so that you can understand at a high level which ones to use for what situations. There are two major of categories of mailbox types that will be discussed here: unbounded and bounded.

Unbounded mailboxes

As their name implies, these mailboxes are not bound by any size limit. You can stuff as many messages into them as possible as long as you have enough heap memory to handle those messages. All of these mailboxes are non-blocking, so they will all provide good performance. The default implementation is called UnboundedMailbox and is a good choice for most work as it's non-blocking and fast, being backed by ConcurrentLinkedQueue.

If you want something even faster, you can consider trying the SingleConsumerOnlyUnboundedMailbox. It cannot be used in a sharing dispatcher (such as the BalancingDispatcher), but it may be able to provide even better performance compared to the default UnboundedMailbox.

If you need priority ordering of the messages the actor receives (regardless of their arrival into the queue), then you can look at using UnboundedControlAwareMailbox. This implementation ensures that any message that extends from akka.dispatch.ControlMessage will be treated with a higher priority and thus handled before regular messages in the mailbox. As the name implies, this is a good choice if you need to get control type messages (things that might change internal behavior in the actor) handled before other messages in the mailbox.

If you need more fine-grained control over the ordering, you can consider using UnboundedPriorityMailbox. As long as the messages you send to it implement Java's comparable interface, then they will be ordered according to the rules defined by your custom compareTo implementation. One thing to consider is that the ordering for items of equal priority is undefined with this mailbox. If you need to have FIFO order enforced for items of equal priority, then you can use the similar UnboundedStablePriorityMailbox instead.

Bounded mailboxes

If you build with actors long enough, you may end up with situations that will require you to have a limit on the total number of messages that an actor can have in its mailbox. This could include situations where you are concerned with the memory buildup of a mailbox that gets too big. This could also cover a scenario where you treat a growing mailbox as a sign of trouble for an actor and use bounding to slow or limit the damage from that trouble.

The most efficient bounded mailbox is the NonBlockingBoundedMailbox. As the name implies, this bounded mailbox does not come at the cost of blocking whoever is trying to put the message into it. That non-blocking nature comes with a negative thought, in that, if you try to put a message into the mailbox and it's at its upper bound, that message will never be delivered and becomes a dead letter.

If you want to mitigate the risk of losing messages when the mailbox is full, then you can consider using a regular BoundedMailbox. With this kind of mailbox, you can choose to block the sender for a specified amount of time if the mailbox is full, waiting for it to go below its capacity before unblocking. This behavior is controlled by the mailbox-push-timeout-time setting that you configure for your mailbox.

Set this to anything other then 0 and you will incur blocking for up to that amount of time, waiting for the mailbox to go below capacity. If that does not happen, then the sender will get unblocked after that time, and the message becomes a dead letter. If you set this to 0, then no blocking will happen, and messages above capacity immediately become dead letters.

Like in the unbounded family of mailboxes, the bounded family has three variants to handle priority-based queueing: BoundedControlAwareMailbox, BoundedPriorityMailbox and BoundedStablePriorityMailbox. These three variants have the same priority-handling behavior as their unbounded counterparts. They also adhere to the same blocking and non-blocking behavior that the regular BoundedMailbox does, being governed by how you decide to set the mailbox-push-timeout-time setting.

Configuring mailboxes for your actors

If you decide that you want to use a mailbox for your actors other than the default, then you first need to decide on the scope of this mailbox change. If you want to use this mailbox for all actor instances created in the system, then simply set the default mailbox setting in your config like so:

akka.actor.default-mailbox{ 
  mailbox-type = "fully qualified class name" 
}

In that example, you need to replace fully qualified class name with the class name of the mailbox that you want to use by default.

You can also change the mailbox just for an individual dispatcher, by setting the mailbox-requirement setting on that dispatcher in your config. So, for example, if I had a custom dispatcher called my-dispatcher, then I could set the mailbox to use for all actor instances that use that dispatcher like this:

my-dispatcher{ 
  mailbox-type = "fully qualified class name" 
}

You can also scope the mailbox down to an individual actor instance if you need that very fine-grained level of control. To do that, you first need to have a config section that represents the mailbox you want to use. That config would look like this:

foo-mailbox{ 
  mailbox-type = "fully qualified class name" 
} 

Then, with that config in place, you could then explicitly set the mailbox of an actor in your code like so:

system.actorOf( 
  Props[FooActor].withMailbox("foo-mailbox"), "foo-actor") 

You could also set that mailbox via deployment config if you didn't want to do it explicitly in code. The deployment config to do that would be as follows:

akka.actor.deployment{ 
  /foo-actor{ 
    mailbox = foo-mailbox 
  } 
}

Then you would create your actor like this to get it to use that mailbox config:

system.actorOf(Props[FooActor], "foo-actor") 

Keep in mind that like with dispatchers, the config path that you are referencing to the mailbox config section must be fully qualified within the context of your complete config tree.

主站蜘蛛池模板: 阜宁县| 沭阳县| 桐庐县| 福安市| 绵阳市| 饶阳县| 邵武市| 贵港市| 汨罗市| 景洪市| 大荔县| 修文县| 通渭县| 太康县| 嵩明县| 礼泉县| 永城市| 开鲁县| 平昌县| 富顺县| 天祝| 信丰县| 西贡区| 石阡县| 邯郸县| 日喀则市| 十堰市| 巧家县| 芮城县| 肇庆市| 桦南县| 儋州市| 延川县| 九寨沟县| 南安市| 合作市| 南皮县| 九龙坡区| 新化县| 奎屯市| 三河市|