代码之家  ›  专栏  ›  技术社区  ›  Max

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

  •  1
  • Max  · 技术社区  · 6 年前

    我有一个简单的AKKAHTTP应用程序,它使用WebSocket。我的请求处理程序具有阻塞调用(如JDBC)。所以,我需要使用一些固定大小的线程池来处理这些代码。

    所以,据我所知,我应该使用 应用程序.conf (像这样) https://github.com/mkuthan/example-akka-http/blob/master/src/main/resources/application.conf )但我不知道如何用固定的线程配置自定义线程池。

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

    • akka-system-akka.actor.default-dispatcher-62
    • 路由-akka.actor.default-dispatcher-79

    我不明白,这些线程池是什么。

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

    akka {
      actor {
        default-dispatcher {
          type = Dispatcher
          executor = "thread-pool-executor"
          thread-pool-executor {
            fixed-pool-size = 40
          }
        }
      }
    }
    

    它的工作非常奇怪:

    1 回复  |  直到 6 年前
        1
  •  1
  •   Ivan Stanislavciuc    6 年前

    你可能用两个名字开始了两个独立的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
      }
    }
    

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