Servlet异步处理请求

2024-04-17

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

根据我在不同地方读到的内容:

请求将由 Servlet 容器中的 HTTP 线程接收和处理,如果发生阻塞操作(如 I/O),则可以将请求移交给另一个线程池,并且接收请求的 HTTP 线程可以返回接收请求并处理下一个请求。

耗时的阻塞操作现在将由线程池中的工作线程承担。

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

如果我是对的,即使处理阻塞操作的线程也会等待该操作完成,从而阻塞资源(并且处理的线程数等于核心数)。

使用异步处理到底能带来什么好处?

如果没有,请赐教。


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

问题。阻塞网络 IO。

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

解决方案 :

一点背景知识,FreeBSD/Linux 中有一种称为 kqueue/epoll 的方法。这两种方法都接受 socketfd 列表(作为函数参数),调用线程会被阻塞,直到一个或多个套接字准备好读取数据,并且这些方法返回这些就绪连接的子列表。参考号http://austingwalters.com/io- Multiplexing/ 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<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 来解决,即与 cpu 的每个核心相对应的一个 Node.js 进程。

无论如何,看看 vert.x,它有点类似 node.js,但用的是 java。 还可以探索 Netty。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Servlet异步处理请求 的相关文章

随机推荐

  • 如何在同一图上显示条形图和折线图

    我无法在同一绘图上显示条形图和折线图 示例代码 import pandas as pd import numpy as np import matplotlib pyplot as plt Df pd DataFrame data np r
  • Python-Selenium 查找不可点击的可点击元素

    我在用python selenium运行自动化测试 在复杂的非公共环境中运行这些测试时 我发现了一些我将标记为 selenium 中的错误的东西 基本上我想做的是在 DOM 中找到一些元素 当它变得可点击时 然后点击它 代码如下 what
  • 处理程序如何/何时被垃圾收集?

    在我的一个类中 我有以下代码 mHandler createHandler private Handler createHandler return new Handler public void handleMessage Message
  • 声明按位运算的掩码

    我是这样的低级操作的新手 我希望有人能指出我在这里犯的明显错误 Input value 00111100 I want to get the value of the bits at indexes 1 3 i e 0111 byte ma
  • SqlConnection 并避免升级到 MSDTC

    当我们需要在应用程序中进行数据库访问时 我们使用以下模式 为了查询 我们有一个带有方法的静态工厂类CreateOpenConnection其作用无非是new SqlConnection myConnectionString 并打电话Open
  • 在 Android 中使用自定义字体

    我想为我正在创建的 Android 应用程序使用自定义字体 我可以从代码中单独更改每个对象的字体 但我有数百个对象 So 有没有办法从 XML 中做到这一点 设置自定义字体 有没有一种方法可以从一个地方的代码中做到这一点 即整个应用程序和所
  • Excel VBA MySql 参数化更新“无效参数类型”

    我正在创建一个界面 用户可以在其中使用 Excel 无缝更改 SQL 数据库 我可以很好地检索数据 但是在更新记录时我得到 无效的参数类型 只需将值连接到查询中就可以正常工作 但是为了防止 SQL 注入 我需要参数化查询 我尝试用该值替换
  • 对于具有单个 Google 帐户的设备,Google 登录不显示帐户选择器

    我正在尝试为 Android 应用程序实现 google plus 登录 我按照谷歌开发者页面上的指南进行操作 https developers google com mobile android getting started https
  • Sublime Text 2 中的“关闭其他”命令快捷方式

    我正在尝试添加 关闭其他 选项卡的快捷方式 但似乎找不到该命令 这就是我正在尝试的 keys super alt w command close others Cmd Option W sort of like Cmd Option H i
  • SOLR 中的子字符串匹配

    我似乎无法弄清楚如何使用 SOLR 查找子字符串匹配 我已经根据前缀找出了匹配 这样我就可以让火腿与汉堡包匹配 我如何搜索 汉堡 来匹配汉堡包 我试过burger但这引发了错误 或 不允许作为 WildcardQuery 中的第一个字符 如
  • python - Atom IDE 如何启用自动完成代码以查看模块中的所有函数

    我正在为我的 python 项目使用atom IDE 在某些情况下有自动完成建议 但我想知道是否可以列出导入模块具有的所有可能功能 例如 如果我导入import urllib当我打字时urlib 并按 ctrl tab 想要查看包含可能使用
  • 如何在 C# 中声明大整数

    下面的代码 C 中 是我尝试转换为 C 的代码 DWORD Func X 4 DWORD arg1 DWORD arg2 DWORD arg3 LARGE INTEGER result 1 0 LARGE INTEGER temp1 0 L
  • 通过 HTTP Post-Commit Hook 将 Github 连接到安全的 Jenkins

    我已经在我的测试服务器上使用 Github 插件设置了 Jenkins 我通过仅允许经过身份验证的用户 匿名用户没有任何权限 和安全连接来保护 Jenkins 不幸的是 Github 提供的提交后挂钩似乎不适用于我的情况 我尝试访问以下网址
  • 在 Jersey 中是否可以访问注入的 HttpServletRequest,而不是代理

    注射时HttpServletRequest在 Jersey JAX RS 资源中 注入的值是代理 例如 Path myResource class MyResource Inject HttpServletRequest request 会
  • 使用 WinApi 使用 C++ 实现多显示器屏幕截图,仅显示 2 个显示器

    我有一个使用 WinApi 和 C 在 Windows 平台上截取屏幕截图的功能 它与一台和两台显示器完美配合 但当我在具有 3 个或更多显示器的计算机上运行它时 它只拍摄两个显示器的照片 我认为我的问题是 主 监视器左侧的监视器内容被切断
  • 提高聚簇索引 GUID 主键的性能

    我有一个包含大量行 10K 的表 它的主键是 GUID 主键是聚集的 该表的查询性能相当低 请提供建议以提高效率 GUID 上的聚集索引不是一个好的设计 GUID 的本质在于它是随机的 而聚集索引则通过键对记录进行物理排序 这两件事是完全矛
  • 如何在 vuejs 中使用 bootstrap 4 主题

    有多个 Bootstrap 4 主题可以让网站的样式和布局变得简单 其中一些要求您的资产文件夹以非常特定的方式布局 例如 https htmlstream com public preview stream ui kit docs html
  • 如何排除不想要的后代?

    我遇到的情况是元素包含n可点击的手柄和n可揭示的元素 div class revealer div class hotspot a class handle href A a div class reveal p Content A p d
  • 如何完全删除颠覆性插件

    我已经安装了 Subversive 并想切换到 Subclipse 插件 通过 关于 Eclipse gt 安装详细信息 gt 卸载 并安装 Subclipse 卸载 Subversive 后 首选项 gt 团队 中现在有两个可用的 SVN
  • Servlet异步处理请求

    当我探索 NodeJS 应用程序和 Java 应用程序如何处理请求时 我遇到了 Servlet 对请求的异步处理 根据我在不同地方读到的内容 请求将由 Servlet 容器中的 HTTP 线程接收和处理 如果发生阻塞操作 如 I O 则可以