在第一次通话时播放框架缓慢

deb*_*ckt 5 scala playframework

我有一个问题,就在启动后的playframework.

我有这个简单的控制器:

@Singleton
class BomberManController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {

  def index() = Action { implicit request: Request[AnyContent] =>
    Ok("test")
  }
}
Run Code Online (Sandbox Code Playgroud)

在第一次调用时,在prod env上,请求需要400ms,在第二次请求需要2ms.

我不明白为什么以及如何优化.在我的项目中,请求必须少于300毫秒.

你有什么想法吗?

PlayVersion:2.6

Mar*_*lic 2

一种选择是创建一个虚拟对象Request并通过 直接将其应用到控制器的构造函数中index.apply(request)。考虑以下方法的定义和调用点warmUp

@Singleton 
class BomberManController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {

  warmUp()

  def index() = Action { implicit request: Request[AnyContent] =>
    Ok("test")   
  }

  private def warmUp() = {
    val requestFactory = new DefaultRequestFactory(HttpConfiguration())
    val request =
      requestFactory.createRequest(
        RemoteConnection("127.0.0.1", false, None),
        "GET",
        RequestTarget("/", "/", Map.empty),
        "HTTP/1.1",
        Headers(),
        TypedMap.empty,
        AnyContentAsEmpty
      )
    index.apply(request)   
  } 
}
Run Code Online (Sandbox Code Playgroud)

在生产中BomberManController,在应用程序启动时实例化,因此warmUp将被调用,进而到达index端点。

要在本地测试此生产行为,请设置play.http.secret.keyapplication.conf启动应用程序

 sbt clean runProd
Run Code Online (Sandbox Code Playgroud)

如果您不希望使用warmUp实用程序方法污染控制器,则可以将此问题分离到实用程序单例中,例如WarmUpUtility,并使用急切的单例绑定。例如:

@Singleton 
class WarmUpUtility @Inject()(bomberManController: BomberManController)() {

  warmUp()

  private def warmUp() = {
    val requestFactory = new DefaultRequestFactory(HttpConfiguration())
    val request =
      requestFactory.createRequest(
        RemoteConnection("127.0.0.1", false, None),
        "GET",
        RequestTarget("/", "/", Map.empty),
        "HTTP/1.1",
        Headers(),
        TypedMap.empty,
        AnyContentAsEmpty
      )
    bomberManController.index.apply(request)
  }

}

// Module should be in the root package 
class Module extends AbstractModule {
  override def configure() = {
    bind(classOf[WarmUpUtility]).asEagerSingleton()
  }
}
Run Code Online (Sandbox Code Playgroud)