学习akka之dispatcher

Dispatcher解析

Dispathcer负责调度并行任务,负责将工作分配给Actor,还可以分配资源用于处理Future的回调,可以理解为Dispatcher和Executor为线程池中线程的调度器。
跟线程池一样,不自己创建Dispatcher时使用的是默认Dispathcer,如果任务中有些耗时任务,容易将默认线程池打满,影响其他任务的调度。

Excutor

Dispatcher基于Excutor,介绍Dispatcher前先介绍下Excutor

  • Excutor分为两种: ForkJoinPool、ThreadPool
    • ThreadPool Excutor: 有一个工作队列,队列中包含了分配给各队列的工作,线程空闲时就从队列中认领工作,允许线程重用,减少线程分配和销毁的开销
    • ForkJoinPool Excutor: 使用一种分治算法,递归地将任务分隔成更小的子任务,然后把子任务分配给不同的线程运行,最后将运行结果组合起来
  • ForkJoinPoll几乎总比ThreadPool效率更高,是我们默认选择

Dispatcher分类

  • Dispatcher: 默认的Dispatcher类型,使用定义的Excutor在Actor中处理消息,大多情况下可以提供最好的性能
  • PinnedDispatcher: 给每个Actor分配独有的线程,为每个Actor都创建一个ThreadPool Excutor,每个Excutor中包含一个线程,可以在单个Actor中处理很多重要工作时候使用这种Dispatcher, 否则不推荐使用
  • CallingThreadDispatcher: 不创建Excutor,在发起调用的线程上执行工作,主要用于测试或者是调试
  • BalancingDispatcher: Pool中的所有Acotr都共享同一个邮箱,并且为POOL中的每个Actor都创建一个县城,只要有Acotr处于空闲状态都会从共享邮箱中领任务,现在已经不推荐直接使用此类Dispatcher了,应该使用前面Router章节中使用到的BalancingPool Router

Dispatcher使用

上面是Dispather的理论部分,下面将着重介绍Dispatcher如何使用。

创建Dispatcher

  • 在 application.conf文件中定义一个Dispatcher,如下所示
  • 参数解析
    • type: Dispatcher的类型,选择符合场景的Dispatcher,这里使用的是默认类型Dispatcher
    • executor: 定义Excutor类型,上面也介绍过两种Excutor
    • parallelism-min: 单核最少线程数,Excutor中最少线程数=parallelism-min*parallelism-factor
    • parallelism-factor: 此项最好配置成机器的CPU核数
    • parallelism-max: 单核最多线程数,Excutor中最多线程数=parallelism-max*parallelism-factor
    • throughput: 跳到另一个Acotr之前每个Actor最多处理消息数量,这个参数为了防止单个Acotr一直占用线程,设置此Acotr最多执行多少消息就要被调度
detect-dispatcher {
  # Dispatcher is the name of the event-based dispatcher
  type = Dispatcher
  # What kind of ExecutionService to use
  executor = "fork-join-executor"
  # Configuration for the fork join pool
  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 = 24.0
    # Max number of threads to cap factor-based parallelism number to
    parallelism-max = 1000
  }
  # Throughput defines the maximum number of messages to be
  # processed per actor before the thread jumps to the next actor.
  # Set to 1 for as fair as possible.
  throughput = 1000
}
  • 使用自定义的Dispatcher,这样创建的DetectRouterActor就都是用自己定义的Dispatcher了
ActorSystem actorSystem = ActorSystem.create("detectTask");
ActorRef routerActorRef = actorSystem.actorOf(
      Props.create(DetectRouterActor.class).withDispatcher("detect-dispatcher");
  • 假如想在使用dispatcher基础上使用Router和指定邮箱,只要这样创建就好了
ActorSystem actorSystem = ActorSystem.create("detectTask");
  ActorRef routerActorRef = actorSystem.actorOf(
      Props.create(DetectRouterActor.class).withMailbox("akka.actor.routermailbox")
          .withDispatcher("detect-dispatcher").withRouter(new SmallestMailboxPool(15000)),
      "detectRouterActor");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值