每个连接的线程与每个请求的线程有什么区别?

时间:2013-03-05 06:50:06

标签: java multithreading http servlets

您能否解释一下在各种servlet实现中实现的两种方法:

  1. 每个连接的线程
  2. 每个请求的主题
  3. 以上两种策略中哪一种更好地扩展?为什么?

5 个答案:

答案 0 :(得分:24)

  

以上两种策略中哪一种更好地扩展?为什么?

每个请求的线程比每个连接的线程更好。

Java线程相当昂贵,通常每个都使用1Mb内存段,无论它们是活动的还是空闲的。如果为每个连接提供自己的线程,则线程通常在连接上的连续请求之间保持空闲。最终,框架需要停止接受新连接(因为它不能创建更多线程)或者开始断开旧连接(如果/当用户醒来时,这会导致连接流失)。

HTTP连接所需的资源远远少于线程堆栈,尽管由于TCP / IP的工作方式,每个IP地址的开放连接数限制为64K。

相反,在每个请求的线程模型中,线程仅在处理请求时关联。这通常意味着服务需要更少的线程来处理相同数量的用户。由于线程使用大量资源,这意味着服务将更具可扩展性。

(请注意,每个请求的线程并不意味着框架必须关闭HTTP请求之间的TCP连接...)


话虽如此,当在每个请求的处理期间存在长暂停时,每请求线程模型并不理想。 (当服务使用comet方法时,它尤其不理想,这种方法涉及保持应答流长时间保持打开状态。)为了支持这一点,Servlet 3.0规范提供了一种“异步servlet”机制,允许servlet的请求方法,用于暂停与当前请求线程的关联。这将释放线程并处理另一个请求。

如果Web应用程序可以设计为使用“异步”机制,则它可能比每个请求的线程或每个连接的线程更具可伸缩性。


<强>后续

  

我们假设一个包含1000张图片的网页。这导致1001个HTTP请求。进一步假设使用HTTP持久连接。使用TPR策略,这将导致1001个线程池管理操作(TPMO)。使用TPC策略,这将产生1个TPMO ......现在,根据单个TPMO的实际成本,我可以想象TPC可能比TPR更好地扩展的场景。

我认为有些事情你没有考虑过:

  • 网页浏览器面临许多要获取以完成网页的网址,可能会打开多个连接。

  • 使用TPC和持久连接,线程必须等待客户端接收响应并发送下一个请求。如果网络延迟很高,则此等待时间可能很长。

  • 服务器无法知道何时可以关闭给定(持久)连接。如果浏览器没有关闭它,它可以“逗留”,将TPC线程关闭,直到服务器超时连接。

  • TPMO开销并不大,尤其是当您将池开销与上下文切换开销分开时。 (你需要这样做,因为TPC将在持久连接上产生上下文切换;见上文。)

我的感觉是,这些因素可能超过TPMO节省了一个专用于每个连接的线程。

答案 1 :(得分:6)

HTTP 1.1 - 支持持久连接,这意味着可以使用相同的HTTP连接接收/发送多个请求/响应。 因此,要并行运行使用相同连接接收的请求,将为每个请求创建一个新的Thread

HTTP 1.0 - 在此版本中,只有一个请求使用连接收到,并且在发送响应后连接已关闭。因此,只为一个连接创建了一个线程。

答案 2 :(得分:3)

Thread per connection是从HTTP Connectionkeep-alive)重用相同multiple requests的概念。

Thread per request将从each requestclient创建一个帖子。服务器可以根据threads创建一些request

答案 3 :(得分:1)

每个请求的线程将为服务器接收的每个HTTP请求创建一个线程。

每个连接的线程将重复使用来自多个请求的相同HTTP连接(保持活动状态).AKA HTTP persistent connection 但请注意,这仅受HTTP 1.1

支持

每个请求的线程速度更快,因为大多数Web容器都使用线程池。

应在服务器上的核心数上设置的最大并行连接数。 更多核心=&gt;更多并行线程。

请参阅此处如何配置... Tomcat 6:http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html

Tomcat 7:http://tomcat.apache.org/tomcat-7.0-doc/config/executor.html

示例

答案 4 :(得分:0)

每个请求的线程应该更好,因为它重用了线程,而某些客户端可能是空闲的。如果你有很多并发用户,他们可以用较少的线程服务,并且具有相同数量的线程会更昂贵。还有一个考虑因素 - 我们不知道用户是否仍在使用应用程序,因此我们无法知道何时销毁线程。使用每个请求机制的机制,我们只使用一个线程池。