你可能用两个名字开始了两个独立的actorsystems
akka-system-akka
和
Routes-akka
,因为您可以在日志中看到两种类型的线程名。
thread-pool-executor
是
ThreadPoolExecutor
由Java运行时定义,而不是固定的THEAD池。
线程池执行器将自动调整池大小(请参见
根据corepoolsize设置的界限(请参见
getcorepoolsize()和maximumpoolsize(请参阅getmaximumpoolsize())。
在方法execute(runnable)中提交新任务时
当corepoolsize线程正在运行时,将创建一个新线程
处理请求,即使其他工作线程空闲。如果有
大于corepoolsize但小于maximumpoolsize线程
运行时,只有队列已满时才会创建新线程。通过
将corepoolsize和maximumpoolsize设置为相同,将创建一个
固定大小的线程池。通过将maximumpoolsize设置为
无边界值,如integer.max_value,允许池
适应任意数量的并发任务。最典型的是
核心池和最大池尺寸仅在施工时设置,但它们
也可以使用setcorepoolsize(int)和
设置maximumpoolsize(int)。
因此,您可以看到它以小于定义的大小开始,并根据传入的任务增加它的线程数。
阅读章节
Keep-alive times
这就解释了线程是如何终止的。
面对眼前的问题:
不超驰
default-dispatcher
由于AKKA将它用于其他目的,即将执行消息传递给所有参与者,这很容易被错误配置。最重要的是,不要在默认调度程序上运行阻塞任务(读取
akka docs
了解更多详细信息)。相反,引入一个单独的调度器并在那里执行阻塞代码。
下面是一个如何处理普通HTTP请求的示例(对不起,我以前没有使用过Web套接字)
val asyncHandler: HttpRequest => Future[HttpResponse] = { req =>
val blockingExecutionContext = system.dispatchers.lookup("blocking-dispatcher")
Future {
// blocking call
HttpRespone(???)
}(blockingExecutionContext) // this can be passed implicitly too
}
Http().bindAndHandleAsync(asyncHandler, "localhost")
blocking-dispatcher
必须在中配置
application.conf
类似于你所做的
默认调度程序
但它是在配置文件的根目录中定义的。
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
}
}
通常,将阻塞执行隔离到单独的执行上下文中,您可以为这种类型的阻塞操作专门配置这些上下文。很容易对执行任务的类型进行微调,因为执行任务的类型受您的限制和控制。