我有一个问题,就在启动后使用playframework。
我有这个简单的控制器:
await page.evaluate(() => {
await Promise((resolve, reject) => {
setInterval(() => {
console.log(document.querySelector('div._captions > p._value').innerText + document.querySelector('div._captions p._hl-value').innerText);
}, 500);
});
});
在第一次通话时,在prod env上,请求需要400ms,在第二次请求需要2ms。
我不明白为什么以及如何优化。在我的项目中,请求必须少于300毫秒。
你有什么想法吗?
PlayVersion:2.6
答案 0 :(得分:0)
一个选项是创建一个虚拟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)
}
}
在生产中BomberManController
在应用程序启动时实例化,因此warmUp
将被调用,而index
会点击application.conf
端点。
要在本地测试此生产行为,请在 sbt clean runProd
中设置play.http.secret.key
并使用
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()
}
}
,并使用eager singleton binding。例如:
{{1}}