Multithreading 如何为Akka HTTP配置特定的调度程序?

Multithreading 如何为Akka HTTP配置特定的调度程序?,multithreading,scala,akka,threadpool,akka-http,Multithreading,Scala,Akka,Threadpool,Akka Http,我有一个简单的Akka HTTP应用程序,它使用websocket。我的请求处理程序有阻塞调用(比如JDBC)。因此,我需要使用一些固定大小的线程池来处理这样的代码 因此,据我所知,我应该使用application.conf(像这样-)。但我不知道如何配置带有固定线程的自定义线程池 当我运行应用程序并进行线程转储时,我会看到两个线程名称: akka-system-akka.actor.default-dispatcher-62 Routes-akka.actor.default-dispatc

我有一个简单的Akka HTTP应用程序,它使用websocket。我的请求处理程序有阻塞调用(比如JDBC)。因此,我需要使用一些固定大小的线程池来处理这样的代码

因此,据我所知,我应该使用application.conf(像这样-)。但我不知道如何配置带有固定线程的自定义线程池

当我运行应用程序并进行线程转储时,我会看到两个线程名称:

  • akka-system-akka.actor.default-dispatcher-62
  • Routes-akka.actor.default-dispatcher-79
我不明白,这些线程池是什么

我尝试设置默认线程池,如下所示:

akka {
  actor {
    default-dispatcher {
      type = Dispatcher
      executor = "thread-pool-executor"
      thread-pool-executor {
        fixed-pool-size = 40
      }
    }
  }
}
它的工作原理非常奇怪:

  • 每个线程池都有自己的40个线程,所以我有80个线程。据我所知,每个启动的调度程序都有自己的40个线程。这很糟糕
  • 它不是固定的线程池-。当应用程序启动时。没有任何线程。然后,当应用程序处理了一些请求时,就会产生线程。当有一段时间没有传入请求时,线程已死亡
您可能启动了两个单独的Actor系统,它们有两个名称
akka系统akka
路由akka
,因为您在日志中看到了两种类型的线程名称

线程池执行器
由java运行时定义,它不是固定的线程池

ThreadPoolExecutor将自动调整池大小(请参阅 getPoolSize())根据corePoolSize设置的边界(请参阅 getCorePoolSize()和maximumPoolSize(请参阅getMaximumPoolSize())。 在方法execute(Runnable)中提交新任务时 如果corePoolSize线程正在运行,则会创建一个新线程以 处理请求,即使其他工作线程处于空闲状态。如果有 大于corePoolSize但小于maximumPoolSize线程 运行时,仅当队列已满时才会创建新线程。通过 将corePoolSize和maximumPoolSize设置为相同,则创建 固定大小的线程池。通过将maximumPoolSize设置为 无界值,如Integer.MAX_值,则允许池 可容纳任意数量的并发任务。最典型的是, 核心池和最大池大小仅在施工时设置,但 也可以使用setCorePoolSize(int)和 setMaximumPoolSize(int)

因此,您可以看到它以小于定义的大小开始,并根据传入的任务增加它的线程数

请阅读
保持活动时间
部分,该部分解释了线程是如何终止的

谈到手头的问题:

不要覆盖默认调度程序,因为akka正在将其用于其他目的,即将执行消息传递给所有参与者,这很容易被错误配置。而且,最重要的是,不要在默认的dispatcher上运行阻塞任务(阅读了解更多详细信息)。相反,引入一个单独的调度器并在那里执行阻塞代码

下面是一个如何使用普通http请求的示例(对不起,我以前没有使用过web套接字)

必须在
application.conf
中配置
blocking dispatcher
,与使用
default dispatcher
类似,但它是在配置文件的根目录中定义的

blocking-dispatcher {
  type = Dispatcher
  executor = "thread-pool-executor"
  thread-pool-executor {
    core-pool-size-min = 2
    core-pool-size-factor = 2.0
    core-pool-size-max = 10
  }
}

通常,将阻塞执行隔离到单独的执行上下文中,您可以专门为此类型的阻塞操作进行配置。由于执行任务的类型受您的限制和控制,因此更容易对这种方法进行微调

为什么不为阻塞调度程序使用固定的线程池大小?@diegramos它可以用作well@IvanStanislavciuc您会建议使用固定大小或类似您的配置吗?还需要添加路由器吗?谢谢你的回复。
blocking-dispatcher {
  type = Dispatcher
  executor = "thread-pool-executor"
  thread-pool-executor {
    core-pool-size-min = 2
    core-pool-size-factor = 2.0
    core-pool-size-max = 10
  }
}