Play Framework:Async vs Sync性能

时间:2014-07-02 20:34:46

标签: multithreading scala asynchronous playframework-2.0

我有以下代码:

  def sync = Action {
      val t0 = System.nanoTime()
      Thread.sleep(100)
      val t1 = System.nanoTime()
      Ok("Elapsed time: " + (t1 - t0) / 1000000.0 + "ms") 
  }

  def async = Action {
    val t0 = System.nanoTime()
    Async { 
          Future{
            Thread.sleep(100)
            val t1 = System.nanoTime()
            Ok("Elapsed time: " + (t1 - t0) / 1000000.0 + "ms") 
            }   
    }
  }

上述代码之间的区别在于,sync将在接收请求的线程上休眠,async将在单独的线程上休眠,以便负责接收请求的线程可以继续接收请求而不会阻塞。当我描述线程时,我看到为异步请求创建的线程数量突然增加。然而,上述两种具有4000并发连接20秒斜坡的方法导致相同的吞吐量和延迟。我希望异步表现更好。为什么会这样?

1 个答案:

答案 0 :(得分:4)

简短的回答是两种方法基本相同。

操作本身始终是异步的(请参阅documentation on handling asynchronous results)。

在这两种情况下,sleep调用都发生在操作的线程池中(这不是最优的)。

Understanding Play thread pools中所述:

  

Play框架是自下而上的异步Web框架。使用迭代器异步处理流。 Play中的线程池被调整为使用比传统Web框架更少的线程,因为play-core中的IO永远不会阻塞。

     

因此,如果您计划编写阻塞IO代码或可能会执行大量CPU密集型工作的代码,则需要确切地知道哪个线程池承载了该工作负载,并且您需要相应地对其进行调整。

例如,此代码片段使用单独的线程池:

Future {
  // Some blocking or expensive code here
}(Contexts.myExecutionContext)

作为其他资源,请参阅this answerthis video,了解有关处理异步操作的更多信息以及thisthis论坛消息,以便就此主题进行广泛讨论。