Play 2.4 在使用 DI 时首次请求需要更多时间

Posted

技术标签:

【中文标题】Play 2.4 在使用 DI 时首次请求需要更多时间【英文标题】:Play 2.4 taking much more time on first request while using DI 【发布时间】:2016-06-23 09:37:19 【问题描述】:

我正在使用带有依赖注入和注入路由生成器的 Play 2.4。但是在第一次请求时,它需要 1200 毫秒,之后,对同一路由的请求需要 20 毫秒。在我对其进行更多调试后,我发现在第一次请求时,它使用 java.lang.classLoader.loadClass(String) 方法加载了大约 1000 个类。

[Loaded org.jboss.netty.handler.codec.frame.FrameDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayingDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpRequestDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayError from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.frame.TooLongFrameException from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpChunk from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpChunkTrailer from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageDecoder$State from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessage from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayingDecoderBuffer from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.UnreplayableOperationException from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.oneone.OneToOneEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpResponseEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil$1 from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil$2 from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.buffer.ChannelBuffers from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]

这些是在第一次请求时加载的一些类。如何在应用程序启动时加载这些类?

【问题讨论】:

我认为这种layz加载类是JVM的正常行为。为什么要更改它? 这也可能来自 Guice。您可以尝试在启动时添加一个钩子以在服务器本身上发出请求以强制它加载类 @Kris 正因为如此,服务器重启后,无论谁发出第一个请求,都需要等待太多。除此之外,它还破坏了 newrelic 中的平均响应时间统计数据。 你是如何运行你的应用程序的? @marcospereira 处于生产模式(使用 sbt dist) 【参考方案1】:

如果您不希望由于 JVM 的延迟加载行为而导致对应用程序的初始请求花费更多时间,一种解决方案是创建外部脚本,该脚本将预热您的应用程序,并且在运行状况检查时不返回 200,直到预热完成完成的。另一种方法是创建将预热您的应用程序的 akka actor。您可以在应用启动后使用 fire-forget 方法 (tell) 初始化此 actor,与上述相同,在预热完成之前使运行状况检查失败,这样 ELB 就不会开始将请求重定向到此实例。

【讨论】:

以上是关于Play 2.4 在使用 DI 时首次请求需要更多时间的主要内容,如果未能解决你的问题,请参考以下文章

使用 Ionic 3 在 IOS 上下载应用程序时首次获取空令牌

VS2017 Xamarin开发Android时首次部署完成后直接闪退

如何在 play framework(scala) 2.4 中获取当前会话或请求对象?

在 Play Framework 2.4 中为 Scala 实现 CORS

在 Play 框架中注入 MongoDB 实例 [java]

Play Framework 1.2.4 在异步线程中同步作业:可能吗?