我是新手一般玩框架和scala。在尝试测试和理解同步和异步操作之间的差异时,使用以下代码:
package controllers
import play.api.mvc._
import play.api.libs.concurrent.Execution.Implicits._
import scala.concurrent.Future
object Application extends Controller {
def async = Action.async {
Logger.info("async start")
val resultF = Future {
Thread.sleep(2000)
Logger.info("async end")
Ok
}
Logger.info("non-blocking")
resultF
}
def sync = Action {
Thread.sleep(2000)
Ok
}
}
运行应用程序时,我在浏览器中有10个选项卡请求" / async"。我的期望是所有请求都需要大约2秒才能完成填充,我会在日志中看到10" async start"条目后跟10" async end"条目。
然而,实际结果是看到" async start"," async end" 10倍。在上一个请求完成之前,下一个请求才开始。似乎async的执行是阻塞的,根本无法处理并发请求。
我的问题是为什么系统会以这种方式运行,以及启用并发请求处理的具体更改。
答案 0 :(得分:2)
使用Action.async
并不会自动表示您没有阻止。这完全取决于您是否使用阻止API。
Thread.sleep
是Future
中的阻止操作,但您没有向ExecutionContext
发信号通知您正在这样做,因此行为将根据ExecutionContext
的不同而有所不同您使用和您的机器有多少处理器。您的代码按预期使用ExecutionContext.global
在这两种情况下,您使用Thread.sleep(2000)
阻止线程。
在这两种情况下,睡眠调用都发生在动作的线程池中(这不是最佳的)。
如了解Play Play线程池中所述:
Play框架是自下而上的异步Web框架。使用迭代器异步处理流。 Play中的线程池被调整为使用比传统Web框架更少的线程,因为play-core中的IO永远不会阻塞。
因此,如果您计划编写阻塞IO代码或可能会执行大量CPU密集型工作的代码,则需要确切地知道哪个线程池承载了该工作负载,并且您需要相应地对其进行调整。
在你的情况下,你只是在两个阻塞线程的情况下等待几秒钟,其中并行因子的默认设置是1。
如果您要阻止该主题,可以使用以下内容:
def async = Action.async {
Logger.info("async start")
val resultF = Future {
blocking{
Thread.sleep(2000)
Logger.info("async end")
Ok
}
}
Logger.info("non-blocking")
resultF
}
答案 1 :(得分:0)
代码工作正常。
使用ab(ApacheBench)或其他方式发送并发请求。
> ab -c 5 -n 5 localhost:9000/async
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient).....done
Server Software:
Server Hostname: localhost
Server Port: 9000
Document Path: /async
Document Length: 0 bytes
Concurrency Level: 5
Time taken for tests: 2.013 seconds
Complete requests: 5
Failed requests: 0
Total transferred: 375 bytes
HTML transferred: 0 bytes
Requests per second: 2.48 [#/sec] (mean)
Time per request: 2013.217 [ms] (mean)
Time per request: 402.643 [ms] (mean, across all concurrent requests)
Transfer rate: 0.18 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 2008 2011 2.0 2011 2013
Waiting: 2007 2011 2.0 2011 2013
Total: 2008 2011 2.0 2011 2013
Percentage of the requests served within a certain time (ms)
50% 2011
66% 2012
75% 2012
80% 2013
90% 2013
95% 2013
98% 2013
99% 2013
100% 2013 (longest request)
我发送了5个并发请求,所有请求都按预期结束(参见上面的Time taken for tests: 2.013 seconds
)