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

2022-09-01 04:38:45

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

  1. 每个连接的线程数
  2. 每个请求的线程数

上述两种策略中哪一种规模更好,为什么?


答案 1

上述两种策略中哪一种规模更好,为什么?

“每个请求的线程数”比“每个连接的线程数”扩展得更好。

Java 线程相当昂贵,通常每个线程使用 1Mb 的内存段,无论它们是活动的还是空闲的。如果为每个连接提供自己的线程,则该线程通常会在连接上的连续请求之间处于空闲状态。最终,框架需要停止接受新连接(因为它无法再创建任何线程)或开始断开旧连接(如果/当用户唤醒时,这会导致连接改动)。

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

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

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


话虽如此,当处理每个请求期间有长时间的暂停时,每个请求的线程模型并不理想。(当服务使用彗星方法时,它尤其不理想,该方法涉及长时间保持回复流打开。为了支持这一点,Servlet 3.0 规范提供了一个“异步 servlet”机制,该机制允许 servlet 的请求方法暂停其与当前请求线程的关联。这将释放线程以转到并处理另一个请求。

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


随访

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

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

  • Web浏览器面临大量URL来完成页面,可能会打开多个连接。

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

  • 服务器无法知道何时可以关闭给定的(持久)连接。如果浏览器不关闭它,它可能会“徘徊”,束缚TPC线程,直到服务器使连接超时。

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

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


答案 2

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

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


推荐