当前位置: 首页 > 知识库问答 >
问题:

在使用NIO连接器部署到Tomcat时,使用Servlet3.0异步是否多余?

充修能
2023-03-14

我看到了这个线程:servlet3.0中的java-async vs servlet3.1中的NIO,但它似乎涉及到servlet3.1NIO(与Tomcat NIO HTTP连接器相反)。

根据我的理解,使用NIO HTTP connectors实现(Tomcat 8及更高版本中的默认值)配置Tomcat处理请求和生成响应的实际工作是在单独的工作线程上完成的,读/写数据的轮询器线程保持畅通。

这似乎与Async Servlet3.0解决的问题相同,因为在请求/响应上完成的工作是在独立于http连接线程的辅助线程上完成的。

那么它们是同一个问题的两个解决方案吗?换句话说,如果servlet容器已经是异步的,那么以异步方式编写代码有什么好处吗?

共有1个答案

师博
2023-03-14

通过了解IO在从容器到应用程序代码的请求处理过程中的不同点上发生的潜在位置,可以更容易地理解这一点。容器连接器(BIO/NIO)的任务是接受套接字连接并将其移交给线程,线程在某个时间点调用Servlet get/post方法。现在,Tomcat NIO connector基本上是容器决定使用Java NIO功能(选择器/通道)以较少的线程处理多个IO通道。selector提供了一种机制,用于监视一个或多个NIO通道,并识别何时一个或多个通道可用于数据传输,因此使用selector容器可以使用一个线程而不是几个线程来管理多个通道。然后,这些就绪通道由线程服务,线程的数量可能比BIO Connector中所需的要少。

顺便说一句--在这个级别上进行了OS级优化,以改善NIO的功能。例如,Java附带了Java.nio.channels.SelectorProvider实现,该实现基于Linux epoll事件通知工具。epoll工具可在Linux2.6和更新的内核中使用。当选择器注册了数千个SelectableChannels时,新的基于Epoll的SelectorProvider实现比传统的基于poll的SelectorProvider实现更具伸缩性。当检测到2.6内核时,默认情况下将使用新的SelectorProvider实现。当检测到2.6之前的内核时,将使用基于轮询的SelectorProvider。

现在回到手头的问题上来。在Servlet3.0之前,整个Servlet处理是同步的,这在Servet3.0中得到了改进,因此get/post方法现在立即返回,但不写入响应,除非通过调用AsyncContextcomplete将其视为完成。到目前为止还好。但还有另一个问题。Servlet处理可能包括读取/写入请求中可用的输入流/输出流。这种木卫一的性质仍然是传统的。Servlet3.0允许异步请求处理,但是IO读/写仍然是旧风格,例如,当从一个速度很慢的客户机读取一个大的请求负载时,线程会阻塞等待数据-因此Servlet3.1的非阻塞IO将起到拯救作用,现在您可以在数据准备就绪时调用您的读/写逻辑,而不是等待它的线程。这是如何在代码中工作的,可以在这里看到。

我们仍然要记住数据库IO(如果有的话)仍然是传统的等待IO。该区域由数据库驱动程序控制,这些驱动程序遵循JDBC API,并且知道有一天他们也会为非阻塞IO提供API。Oracle已经领导了一个类似异步数据库访问的项目,它看起来也在利用Java NIO。这将为使整个请求处理非阻塞铺平道路。

另外,Spring正在做的另一项有希望的工作--反应型关系数据库连接,旨在解决这个问题。

 类似资料:
  • 我想用maven部署一个小型Web应用程序。我下载并配置了tomcat,并告诉IntelliJ在Run/Debug config中使用它,如下所示。我还将其配置为构建神器“战争爆炸”。 问题是,每次我运行项目时,都会出现一个错误,即: 工件JDBCTest:war:服务器未连接。部署不可用。 这是我的带有错误日志的dropbox,pom。xml、servlet类等。 我真的需要一些建议。

  • 我的ant-script和Tomcat有问题。我想创建一个ant-scipt,它使用Jenkins在我的tomcat-server上构建、编译和部署我的GWT应用程序。为此,我使用来自catalina(catalina-ant.jar)的undeploy and deploy任务。但是我得到了这个错误: 构建失败d:\jenkins\jobs\homepageTomcat\workspace\BU

  • 这是MyResource: 和我的web.xml: 在客户端,我使用这个url:http://localhost:8080/[projectname]/webapi/helloworld 谢了!

  • 问题内容: 有没有办法使javascript 关键字在函数外部起作用?我希望能够冻结整个调用堆栈(而不是仅冻结函数的其余部分),以便在特定的Promise返回值后可以恢复。令人遗憾的是,目前尚未确定或尚未实施类似这样的强大功能。我试图使nodent.js正常工作,但是由于我的自定义加载程序和动态功能,不幸的是不切实际。 问题答案: 如果您正在寻找黑客,而不是适当的基于诺言的并发解决方案,请看一下节

  • 我有一个Spring Boot Java应用程序,我已经按照教程进行了设置,以便构建一个WAR。我正试图使用Jenkins将这个WAR文件部署到远程Tomcat 7服务器。当我告诉Jenkins构建和部署应用程序时,登录Jenkins表明一切都是成功的。如果我登录到托管Tomcat的远程服务器,我可以看到WAR被复制到服务器。如果我查看日志文件,它会显示以下内容: 如果我进入tomcat管理器应用