scala - 为什么非阻塞 Web 请求高效,因为我们在这两种情况下都持有服务器线程

标签 scala playframework

问题是关于 Play 框架的,尽管概念是通用的。

引用自:

https://www.playframework.com/documentation/2.6.18/ScalaAsync

The web client will be blocked while waiting for the response, but nothing will be blocked on the server, and server resources can be used to serve other clients.

Using a Future is only half of the picture though! If you are calling out to a blocking API such as JDBC, then you still will need to have your ExecutionStage run with a different executor, to move it off Play’s rendering thread poo

我理解原始Web应用程序线程将被释放的部分,但是仍然需要另一个线程来实际执行CPU密集型操作,然后计算结果,该结果将传播到客户端(同时被阻止)。

还有什么比在戏剧 Action 代码中同步执行更好的方法呢?我们必须增加线程数量(因为阻塞请求将消耗线程),但是服务器上的事件线程总数将保持不变。

有人还可以阐明 Play 如何跟踪阻塞的客户端线程并在非阻塞操作场景中返回响应吗?

最佳答案

使用不同的线程池进行渲染和长时间运行的操作是可取的,因为这样长时间运行的操作可以使用其池中的所有线程而不会阻塞渲染。

想象一下这种情况:

  1. 10 个客户端发出需要长时间运行操作的资源请求。
  2. 然后,客户端尝试访问无法访问的资源。

这里有两种处理方法:

  1. 您有一个包含 10 个线程的池,可用于所有用途。这些填补了您的长时间运行的操作,而另一个客户端 - 谁有一个更简单的请求! — 必须等待其中一个长时间运行的调用完成。
  2. 您有两个线程池,一个有 5 个线程用于渲染,另一个有 5 个线程用于长时间运行的操作。渲染线程快速将长时间运行的操作交给另一个池,使它们能够响应第十一个客户端的请求。

第二种情况肯定更好,但我想指出拥有多个线程池的另一个原因:有时不同的操作需要不同种类的系统资源。例如,渲染可能受 CPU 限制,而数据库调用可能主要受网络限制,或者受 CPU 限制但在不同的计算机(数据库服务器)上完成。如果您对两者使用相同的线程池,则线程可能会忙于等待网络调用完成,而 CPU 几乎处于空闲状态,即使您有多个 CPU 密集型任务排队。这会导致资源使用效率低下,因此您应该为不同类型的任务使用不同的线程池。

关于scala - 为什么非阻塞 Web 请求高效,因为我们在这两种情况下都持有服务器线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52195117/

相关文章:

mongodb - Casbah:没有隐式 View 可用错误

java - 将动态值传递给路由 URI

scala - Akka Actor如何仅处理最新消息

java - 在 Java 中访问 Scala 元组元素的正确方法是什么?

scala - 如何使用Scala在Spark 2.1中将以毫秒为单位的字符串列转换为以毫秒为单位的时间戳?

java - 使嵌套的http请求java异步

scala - 从 scala 将文档插入 mongodb 时出错

scala - Akka 和 Vert.x 消息传递模型的区别

java - Playframework 从 2.4 迁移到 2.5 : java. lang.IllegalStateException:尝试调用 Materialize()

java - PlayFramework2 : css not loading on heroku