Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用tomcat和spring进行异步http请求处理_Java_Multithreading_Spring Mvc_Tomcat_Asynccontroller - Fatal编程技术网

Java 使用tomcat和spring进行异步http请求处理

Java 使用tomcat和spring进行异步http请求处理,java,multithreading,spring-mvc,tomcat,asynccontroller,Java,Multithreading,Spring Mvc,Tomcat,Asynccontroller,这是我的第一个问题,所以请耐心点:) 我正在尝试创建一个服务: 接收包含要查询的URL的HTTP GET请求 对于单个GET请求,服务提取URL 查询有关URL的本地数据库 如果在数据库中找到结果,它将返回给客户,如果没有,它将需要查询一些外部服务(这可能需要相对较长的时间来响应) 将URL的结果返回给客户端 我在虚拟机上运行这个,并使用spring运行Tomcat7。 我会提前道歉,并说我对Tomcat还很陌生 无论如何,我期望有很多并发的GET请求(数十万个并发请求) 我基本上想要实现的是使

这是我的第一个问题,所以请耐心点:)

我正在尝试创建一个服务:

  • 接收包含要查询的URL的HTTP GET请求
  • 对于单个GET请求,服务提取URL
  • 查询有关URL的本地数据库
  • 如果在数据库中找到结果,它将返回给客户,如果没有,它将需要查询一些外部服务(这可能需要相对较长的时间来响应)
  • 将URL的结果返回给客户端
  • 我在虚拟机上运行这个,并使用spring运行Tomcat7。 我会提前道歉,并说我对Tomcat还很陌生

    无论如何,我期望有很多并发的GET请求(数十万个并发请求) 我基本上想要实现的是使这个服务尽可能具有可伸缩性(如果这不可能,那么至少要有一个可以同时处理数十万个请求的服务)

    我已经读了很多关于服务中异步请求处理的书,尤其是在Tomcat中,但是我仍然不清楚一些事情:

  • 从tomcat官方网站上看,tomcat似乎包含接受线程数和工作线程数。 如果是这样,为什么要使用AsyncContext?释放Tomcat的工作线程并在应用程序中占用不同的线程来执行完全相同的操作有什么好处?(系统中仍有1个活动线程)
  • 有点类似于第一个问题,但是创建AsyncContext并将其用于不同的线程有什么好处吗?(我的应用程序中创建的线程池中的线程)
  • 关于同一个问题,我已经看到,我还可以返回一个Callable或DeferredResult,并使用Tomcat的一个线程或我自己的一个线程来处理它。返回可调用或使用延迟结果是否比仅处理来自请求的AsyncContext有任何好处
  • 另外,如果我决定返回一个可调用的线程,Tomcat从哪个线程池获取线程来处理我的可调用线程?这里使用的线程是否与我前面提到的Tomcat的工作线程相同?如果是这样的话,释放一个Tomcat工作线程并使用另一个线程有什么好处
  • 我从Oracle的文档中看到,我可以向AsyncContext传递一个将被并发处理的可运行对象,用于执行此可运行对象的线程来自哪里?我能控制它吗?另外,将AsyncContext传递给一个可运行的线程比将AsyncContext传递给我的线程有什么好处
  • 很抱歉,我问了这么多关于同样事情的问题,但我和我的同事就这些问题争论了一个多星期,没有任何具体的答案

    我还有一个更一般的问题: 您认为使我描述的服务可扩展的最佳方法是什么?(暂时抛开增加更多的机器不谈),您是否可以发布一些针对特定解决方案的示例或参考资料

    我会发布更多我一直在看的链接,但我目前的声誉不允许这样做。 如果有任何可以理解的参考资料或具体的例子,我将不胜感激。显然,我很乐意澄清任何相关问题


    干杯

    这里面有很多问题,但我会尝试解决其中的一些问题

    异步I/O是一件好事,特别是在服务大量请求的服务器上——它允许您使用更少的线程来处理更多的请求。对于您正在编写的代理,您确实希望您的HTTP客户机(对外部URL发出请求)也是异步的,这样无论是处理请求还是接收远程响应都不会阻塞I/O

    也就是说,一般来说,使用Tomcat或JavaEE服务器来完成这项工作可能比使用这样的框架从一开始就是异步的要困难得多,因为这些服务器都附带了异步I/O。作为构建在Netty之上的框架的作者,我有点偏见

    为了演示您需要执行所描述的操作的代码有多少,我编写了一个小型服务器,它执行您在3个Java源文件中描述的操作—它构建了一个独立的JAR,您可以使用
    Java-JAR
    来运行它,并尝试对其进行清晰的注释

    归根结底,网络应用程序大部分时间都在等待I/O的发生。特别是在代理的情况下,使用传统的线程化I/O,您会收到一个请求,而接收请求的线程将负责同步响应该请求——这意味着,如果它必须向另一台服务器发出网络请求,该线程将被阻塞,等待来自远程服务器的响应。这意味着线程不能用于任何其他用途。因此,如果您有10个线程,并且所有线程都在等待响应,那么在其中一个线程完成并释放一个线程之前,您的服务器无法响应更多的请求。对于异步I/O,当某些I/O完成时,您会得到一个回调。换句话说,在操作系统将您的数据刷新到套接字并从网卡中取出之前,您的代码不是静止不动,而是在有事情要做时(比如代理请求的响应)只需轻轻地敲击一下您的肩膀即可。当您的代码等待HTTP请求完成时,发送代理请求的线程可以自由地用于处理另一个请求,这意味着一个线程可以对一个请求做一些工作,对另一个请求做一些工作,最终完成第一个请求。由于线程是由操作系统提供的有限资源,这允许您用更少的硬件做更多的事情

    至于
    可调用的
    延迟的结果
    ,使用
    可调用的
    只会在工作发生时移动