首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Servlet异步处理请求

Servlet异步处理请求
EN

Stack Overflow用户
提问于 2014-07-17 06:29:43
回答 2查看 2.1K关注 0票数 7

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

从我在不同地方读到的:

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

耗时的阻塞操作现在将由线程池的工作人员进行。

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

如果我说得对,甚至处理阻塞操作的线程也会等待该操作完成,从而阻塞资源(所处理的线程数等于核数)。 使用异步处理的好处究竟是什么?

如果没有,请告诉我。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-17 07:03:31

是的,在这个场景中,阻塞操作将在它自己的线程中执行,并且会阻塞一些资源,但是您的HTTP线程现在可以自由地处理其他一些操作,这些操作可能并不耗时。

异步处理的好处是能够在等待重量级操作响应时继续处理其他请求,而不是哑阻塞HTTP线程。

票数 1
EN

Stack Overflow用户

发布于 2014-07-17 08:07:38

我可以用Node.js来解释这些好处(在其他地方同样适用)。

问题所在。阻塞网络IO。

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

解决办法:

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

现在假设您对上述方法有了一种感觉。假设有一个名为EventLoop的线程,它调用上面的方法epoll/kqueue。

因此,在java中,您的代码将如下所示。

代码语言:javascript
复制
 /*Called by Event Loop Thread*/

while(true) {

   /**
     * socketFD socket on which your server is listening
     * returns connection which are ready 
     */ 
    List<Connection> 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();     
   }

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

上述方法有两个缺点。

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

首先,可以考虑集群Node.js的缺点,即处理与每个node.js内核对应的一个node.js进程。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24796334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档