【发布时间】:2016-12-26 11:17:19
【问题描述】:
几天前,我遇到了客户端在 20 秒后收到来自播放应用程序的响应的问题。我在生产服务器上设置了新的 relic,它不断告诉 RPM、平均响应时间、CPU 和内存使用情况等。根据新的 relic 响应时间不超过 500 毫秒,但我验证客户端在 20 秒后收到响应.为了挖掘更多信息,我添加了日志,其中显示了在播放应用程序中提供请求所需的时间。我按以下方式添加了日志过滤器:
val noCache = Filter { (next, rh) =>
val startTime = System.currentTimeMillis
next(rh).map { result =>
val requestTime = System.currentTimeMillis - startTime
Logger.warn(s"${rh.method} ${rh.uri} took ${requestTime}ms and returned ${result.header.status}")
result.withHeaders(
PRAGMA -> "no-cache",
CACHE_CONTROL -> "no-cache, no-store, must-revalidate, max-age=0",
EXPIRES -> serverTime
)
}
}
private def serverTime = {
val calendar = Calendar.getInstance()
val dateFormat = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z")
dateFormat.setTimeZone(calendar.getTimeZone)
dateFormat.format(calendar.getTime())
}
在我的负载测试期间,我向 play-app 发送了大约 3K 个并发请求,并为所有请求捕获了 TCPDUMP。以下是我的观察:
- 根据 play-application-log,play 应用程序响应的最长时间为 68 毫秒。
- 根据 TCPDUMP,响应任何请求所需的最长时间约为 10 秒。
- 根据新遗物的最大响应时间约为 84 毫秒(因为这与我添加的日志非常接近,我们可以忽略这个)
据我所知,过滤器是请求-响应生命周期的最后阶段之一。因此,如果过滤器中的日志显示请求需要 68 毫秒,而 TCPDUMP 声称响应是在 10 秒后发送的,那么是什么导致了响应请求的延迟?
我了解在多线程环境中,执行特定语句后可能会发生上下文切换。但是上下文切换不应该造成这么多的延迟。根据新遗物,此负载测试期间的线程数少于 50 个。
有人能解释一下是什么原因造成的吗?欢迎您提供关于请求-响应生命周期的深刻见解。
【问题讨论】:
标签: scala playframework playframework-2.0