极速慢玩框架2.3请求处理代码
Extremely slow play framework 2.3 request handling code
我的方法性能极慢:
HttpRequestDecoder.unfoldAndFireMessageReceived()
和
Future$PromiseCompletingRunnable.run()
这两种方法使用服务器中每个事务的大约一半时间。它发生在低流量和高使用时间。
例如,在凌晨 1 点只有我对应用程序发出请求时,我在新遗迹中得到了这样的图表:
在这个事务中只有这两个方法消耗了整整一秒,比通过hibernate访问数据库更慢!再一次,应用程序中只有一个用户。
如果交易量较大,则需要更多时间:
在这种情况下,这两种方法平均消耗 2.5 秒,而我自己的代码消耗 1.5 秒,总共消耗 4 秒。那时我想,也许这只是对新遗物指标的误导。也许 newrelic 显示了这个方法的名称,但它确实是我写的代码。所以我决定获得这样的自定义指标:
playController(){
//Start timer
//do the job
//stop the timer() and send metric to new relic
//return;
}
结果是我的代码用了 1.5 秒。所以这次真的是play request handler在消耗时间。
这种行为在高负载时会杀死我的应用程序。当吞吐量约为每分钟 500 个请求时,这两种方法最多可以消耗 20 秒(不是真正的高吞吐量!)但我的代码保持稳定在最多 3 秒。
我真的不认为这是一个线程问题,因为它甚至在只有一个用户的情况下也会发生,但是当有许多并发请求时它就会成为真正的问题。我尝试像文档中提到的那样更改 "synchronous apps" 的线程数,但我没有得到任何性能变化,甚至变得更糟。
我很关心这个问题,因为玩了两年多的邮件列表里也有类似的案例,没有人回答!:
在 Whosebug 中甚至还有一个类似的问题,但对于 play 2.1 没有答案也没有明显的 activity:
Slow transactions in NewRelic having Play Framework as backend
知道是什么导致了这种行为吗?
一个月后我终于可以说这个问题已经解决了。答案是完全没有问题。 新的 relic 默认工具无法正确报告 Play Framework 2 事务消耗的时间,我什至可以说是通过运行在 Netty 上的任何异步框架。
为了得出这个结论,我不得不在最有问题的交易中包含一些自定义指标,只是为了发现我的自定义工具使用的时间比新遗物报告的要少得多。
之后,我使用 firebug 在客户端中进行了测试,报告的时间与我的自定义指标相匹配。
就在一周前,我在 newrelic 论坛上发现了这个 post:
在禁用 netty、akka 的所有检测并在 newrelic 配置文件中使用这些行之后,我终于开始通过默认检测获得现实时间:
common: &default_settings
class_transformer:
# Disable all Akka instrumentations
com.newrelic.instrumentation.akka-2.0:
enabled: false
com.newrelic.instrumentation.akka-2.1:
enabled: false
com.newrelic.instrumentation.akka-2.2:
enabled: false
# Disable all Netty instrumentations
com.newrelic.instrumentation.netty-3.4:
enabled: false
com.newrelic.instrumentation.netty-3.8:
enabled: false
com.newrelic.instrumentation.netty-4.0.0:
enabled: false
com.newrelic.instrumentation.netty-4.0.8:
enabled: false
# Disable all Play 2 instrumentations
com.newrelic.instrumentation.play-2.1:
enabled: false
com.newrelic.instrumentation.play-2.2:
enabled: false
com.newrelic.instrumentation.play-2.3:
enabled: false
# New in Release 3.22, the Play 2.4 instrumentation does not respect
# the older play2_instrumentation configuration setting
com.newrelic.instrumentation.play-2.4:
enabled: false
# Disable all Scala-language instrumentations
com.newrelic.instrumentation.scala-2.9.3:
enabled: false
在 newrelic 文档中说:
You may choose to disable some or all of this instrumentation if you
find that the metrics reported aren't valuable to you, or if the
instrumentation incurs more overhead than you would like. If you
selectively disable some of the instrumentation, some segments of
activity will not be reported and your total time will be understated.
但恕我直言,它应该说:
You may choose to disable ALL of this instrumentation if you want to
get realistic metrics.
为什么会出现这种行为?
这个问题极大地误导了我的团队(以及项目发起人)。我并没有完全责怪 Newrelic,这个工具很有用,但这给我留下了一个教训,让我不要只相信一种工具。
我的方法性能极慢:
HttpRequestDecoder.unfoldAndFireMessageReceived()
和
Future$PromiseCompletingRunnable.run()
这两种方法使用服务器中每个事务的大约一半时间。它发生在低流量和高使用时间。
例如,在凌晨 1 点只有我对应用程序发出请求时,我在新遗迹中得到了这样的图表:
在这个事务中只有这两个方法消耗了整整一秒,比通过hibernate访问数据库更慢!再一次,应用程序中只有一个用户。
如果交易量较大,则需要更多时间:
在这种情况下,这两种方法平均消耗 2.5 秒,而我自己的代码消耗 1.5 秒,总共消耗 4 秒。那时我想,也许这只是对新遗物指标的误导。也许 newrelic 显示了这个方法的名称,但它确实是我写的代码。所以我决定获得这样的自定义指标:
playController(){
//Start timer
//do the job
//stop the timer() and send metric to new relic
//return;
}
结果是我的代码用了 1.5 秒。所以这次真的是play request handler在消耗时间。
这种行为在高负载时会杀死我的应用程序。当吞吐量约为每分钟 500 个请求时,这两种方法最多可以消耗 20 秒(不是真正的高吞吐量!)但我的代码保持稳定在最多 3 秒。
我真的不认为这是一个线程问题,因为它甚至在只有一个用户的情况下也会发生,但是当有许多并发请求时它就会成为真正的问题。我尝试像文档中提到的那样更改 "synchronous apps" 的线程数,但我没有得到任何性能变化,甚至变得更糟。
我很关心这个问题,因为玩了两年多的邮件列表里也有类似的案例,没有人回答!:
在 Whosebug 中甚至还有一个类似的问题,但对于 play 2.1 没有答案也没有明显的 activity:
Slow transactions in NewRelic having Play Framework as backend
知道是什么导致了这种行为吗?
一个月后我终于可以说这个问题已经解决了。答案是完全没有问题。 新的 relic 默认工具无法正确报告 Play Framework 2 事务消耗的时间,我什至可以说是通过运行在 Netty 上的任何异步框架。
为了得出这个结论,我不得不在最有问题的交易中包含一些自定义指标,只是为了发现我的自定义工具使用的时间比新遗物报告的要少得多。
之后,我使用 firebug 在客户端中进行了测试,报告的时间与我的自定义指标相匹配。
就在一周前,我在 newrelic 论坛上发现了这个 post:
在禁用 netty、akka 的所有检测并在 newrelic 配置文件中使用这些行之后,我终于开始通过默认检测获得现实时间:
common: &default_settings
class_transformer:
# Disable all Akka instrumentations
com.newrelic.instrumentation.akka-2.0:
enabled: false
com.newrelic.instrumentation.akka-2.1:
enabled: false
com.newrelic.instrumentation.akka-2.2:
enabled: false
# Disable all Netty instrumentations
com.newrelic.instrumentation.netty-3.4:
enabled: false
com.newrelic.instrumentation.netty-3.8:
enabled: false
com.newrelic.instrumentation.netty-4.0.0:
enabled: false
com.newrelic.instrumentation.netty-4.0.8:
enabled: false
# Disable all Play 2 instrumentations
com.newrelic.instrumentation.play-2.1:
enabled: false
com.newrelic.instrumentation.play-2.2:
enabled: false
com.newrelic.instrumentation.play-2.3:
enabled: false
# New in Release 3.22, the Play 2.4 instrumentation does not respect
# the older play2_instrumentation configuration setting
com.newrelic.instrumentation.play-2.4:
enabled: false
# Disable all Scala-language instrumentations
com.newrelic.instrumentation.scala-2.9.3:
enabled: false
在 newrelic 文档中说:
You may choose to disable some or all of this instrumentation if you find that the metrics reported aren't valuable to you, or if the instrumentation incurs more overhead than you would like. If you selectively disable some of the instrumentation, some segments of activity will not be reported and your total time will be understated.
但恕我直言,它应该说:
You may choose to disable ALL of this instrumentation if you want to get realistic metrics.
为什么会出现这种行为?
这个问题极大地误导了我的团队(以及项目发起人)。我并没有完全责怪 Newrelic,这个工具很有用,但这给我留下了一个教训,让我不要只相信一种工具。