一、概要
Dispatchers are the heart of the Akka application and this is what makes it
humming. Routers on the other hand, route incoming messages to outbound actors
二、Dispatcher 类型
Dispatcher
特点如下:• Every actor is backed by its own mailbox
• The dispatcher can be shared with any number of actors
• The dispatcher can be backed by either thread pool or fork join pool
• The dispatcher is optimized for non-blocking code
Pinned dispatcher
特点• Every actor is backed by its own mailbox.
• A dedicated thread for each actor implies that this dispatcher cannot be
shared with any other actors.
• The dispatcher is backed by the thread pool executor.
• The dispatcher is optimized for blocking operations. For example, if the code
is making I/O calls or database calls, then such actors will wait until the task
is finished. For such blocking operation, the pinned dispatcherperforms
better than the default dispatcher
Balancing dispatcher
特点:• There is only one mailbox for all actors
• The dispatcher can be shared only with actors of the same type
• The dispatcher can be backed by a either thread pool or fork join pool
- Calling thread dispatcher
特点:
• Every actor is backed by its own mailbox
• The dispatcher can be shared with any number of actors
• The dispatcher is backed by the calling thread
三、mailboxes 类型
• Blocking queue: Blocking queue means a queue that waits for space to
become available before putting in an element and similarly waits for t
queue to become non-empty before retrieving an element
• Bounded queue: Bounded queue means a queue that limits the size of
queue; meaning you cannot add more elements than the specified size
四、Thread pool executor 与 Fork join executor
• Thread pool executor: Here, the idea is to create a pool of worker threads.
Tasks are assigned to the pool using a queue. If the number of tasks exceeds
the number of threads, then the tasks are queued up until a thread in the
pool is available. Worker threads minimize the overhead of allocation/
deallocation of threads.
• Fork join executor: This is based on the premise of divide-and-conquer. The
idea is to divide a large task into smaller tasks whose solution can then be
combined for the final answer. The tasks need to be independentto be able
run in parallel.
计算规则:
• Minimum number of threads that will be allocated
• Maximum number of threads that will be allocated
• Multiplier factor to be used (based on number of CPU cores available)
For example, if the minimum number is defined as 3 and the multiplier factor is
2, then the dispatcher starts with a minimum of 3 x 2 = 6 threads. The maximum
number defines the upper limit on the number of threads. If the maximum number is
8, then the maximum number of threads will be 8 x 2 = 16 threads
Thread pool executor 配置方式:
# Configuration for the thread pool
thread-pool-executor {
# minimum number of threads
core-pool-size-min = 2
# available processors * factor
core-pool-size-factor = 2.0
# maximum number of threads
core-pool-size-max = 10
}
Fork join executor 配置方式
# Configuration for the fork join pool
fork-join-executor {
# Min number of threads
parallelism-min = 2
# available processors * factor
parallelism-factor = 2.0
# Max number of threads
parallelism-max = 10
}
完整的一个dispatch 配置
my-dispatcher {
type = Dispatcher
executor = "fork-join-executor"
fork-join-executor {
parallelism-min = 2
parallelism-factor = 2.0
parallelism-max = 10
}
throughput = 100
mailbox-capacity = -1
mailbox-type =""
}
代码实现
ActorSystem _system = ActorSystem.create("dispatcher",
ConfigFactory.load().getConfig("MyDispatcherExample"));
ActorRef actor = _system.actorOf(new Props(MsgEchoActor.class)
.withDispatcher("my-dispatcher"));