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

Asa*_*bal 4 scala playframework

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

引用自:

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

在等待响应时将阻止Web客户端,但服务器上不会阻止任何内容,并且可以使用服务器资源为其他客户端提供服务.

使用未来只是图片的一半!如果你正在调用一个阻塞的API,比如JDBC,那么你仍然需要让你的ExecutionStage运行一个不同的执行器,将它从Play的渲染线程poo移开

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

如何比在play的动作代码中同步执行执行更好?我们必须增加线程数(因为阻塞请求将使用线程),但服务器上活动线程的总数将保持不变.

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

Bri*_*hon 6

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

想象一下这种情况:

  1. 10个客户端请求需要长时间运行的资源.
  2. 然后客户端尝试访问没有的资源.

以下是两种可以处理的方法:

  1. 你有一个10线程的池用于一切.这些填充了您的长期运行,而另一个客户 - 他们有更简单的请求! - 必须等待其中一个长时间通话完成.
  2. 你有两个线程池,一个有5个线程用于渲染,另一个有5个线程用于长时间运行.渲染线程快速地将长时间运行的操作工作到另一个池,使它们能够响应第十一个客户端的请求.

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