Servlet异步处理请求

当我正在探索NodeJS应用程序和Java应用程序如何处理请求时,我遇到了Servlet对请求的异步处理。

从我在不同的地方读到的:

请求将由来自Servlet容器的HTTP线程接收和处理,并且在阻塞操作(如I / O)的情况下,请求可以移交给另一个Threadpool,并且接收请求的HTTP线程可以返回接收并处理下一个请求。

现在,来自Threadpool的工作人员将占用耗时的阻塞操作。

如果我理解的是正确的,我有以下问题:

即使是处理阻塞操作的线程也会等待该操作完成,因此阻塞资源(并且处理的线程数等于内核数),如果我是正确的话。

通过使用异步处理,这里获得了什么?

如果没有,请赐教。

是的,在这种情况下,阻塞操作将在其自己的线程中执行并将阻止某些资源,但您的HTTP线程现在可以自由地处理可能不那么耗时的其他一些操作。

您获得的异步处理能够在等待重量级操作响应而不是阻止HTTP线程的情况下继续处理其他请求。

我可以解释Node.js方面的好处(同样适用于其他地方)。

问题。 阻止网络IO。

假设您要与服务器建立连接,为了从连接读取,您将需要一个线程T1,它将通过网络读取该连接的数据,此读取方法是阻塞的,即您的线程将无限期地等待,直到有任何数据阅读。 现在假设你有另一个连接,现在要处理这个连接,你必须创建另一个线程T2。 很可能这个线程可能再次被阻塞以读取第二个连接上的数据,因此这意味着您可以处理尽可能多的连接,因为您可以处理系统中的线程。 这称为线程每请求模型。 由于大量的上下文切换和调度,创建大量线程会降低系统性能。 该模型不能很好地扩展。

方案:

有点背景,FreeBSD / Linux中有一种叫做kqueue / epoll的方法。 这两个方法都接受一个socketfd列表(作为函数参数),调用线程被阻塞,直到一个或多个套接字有数据准备好读取,这些方法返回那些就绪连接的子列表。 参考。 http://austingwalters.com/io-multiplexing/

现在假设您对上述方法有所了解。 想象一下,有一个线程被调用为EventLoop,它调用上面的方法epoll / kqueue。

所以在java中你的代码看起来像这样。

/*Called by Event Loop Thread*/ while(true) { /** * socketFD socket on which your server is listening * returns connection which are ready */ List readyConnections = epoll( socketFd ); /** * Workers thread will read data from connection * which would be very fast as data is already ready for read * So they don't need to wait. */ submitToWorkerThreads(readyConnections); /** * callback methods are queued by worker threads with data * event loop threads call this methods * this is where the main bottleneck is in case of Node.js * if your callback have any consuming task lets say loop * of 1M then you Event loop will be busy and you can't * accept new connection. In practice in memory computation * are very fast as compared to network io. */ executeCallBackMethodsfromQueue(); } 

所以现在你看到上面的方法可以接受比每个请求模型更多的连接,工作线程也没有被卡住,因为它们只会读取那些有数据的连接。 当工作线程将读取整个数据时,它们将使用您在侦听时提供的回调处理程序将队列中的响应或数据排入队列。 这个回调方法将再次由Event Loop Thread执行。

上述方法有两个缺点。

  1. 无法正确使用多处理器的所有核心。
  2. Long In内存计算会显着降低性能。

第一个缺点是可以处理Clustered Node.js,即对应于cpu的每个核心的一个node.js进程。

无论如何看看vert.x这是类似的node.js,但在java中。 还探索Netty。