当HTTP servlet请求超时时会发生什么?

4

我有一个耗时的逻辑需要从http servlet中调用。 当请求超时时会发生什么? Servlet容器会挂起基础的http线程吗?还是它将继续运行?


我认为它应该保持运行状态。为了尝试它,编写一个只进入无限循环的HttpServlet。附加调试器以找出该线程发生了什么。 - austin
2个回答

2

Servlet线程仍在运行,因为超时是客户端的行为,唯一的影响是客户端关闭请求的输入流(servlet的输出流),结果可能无法发送到客户端。


我认为超时是特定于Servlet容器的。一旦达到超时,Servlet通常会发送类似于HTTP错误408请求超时的内容。我不是在询问由于连接不良等原因导致超时时会发生什么。 - adrift
客户端可以指定HTTP请求超时时间。 - BlackJoker

2

它将继续运行,不知道请求的客户端可能已经消失。

线程池

应用服务器通常包含一个有界的线程池来服务请求。这些池可以针对每个 Web 应用程序或甚至是 Servlet / EJB 进行定制。当您运行一个长时间的线程(或永久线程)时,它会利用线程池中的一个线程,并在完成之前不会返回该资源。这可能会导致线程池达到其最大大小,并最终降低对 Web 应用程序的调用性能。

还有一个无限制的线程池概念,其中池可以使用的线程数仅受硬件限制。这可能不是一个好主意,因为无限制的线程池可能会影响整个机器,而不仅仅是导致问题的 WAR / 代码的“服务质量”属性。

卡住的线程

一些应用服务器具有检测此类情况并将这些线程标记为卡住的预留。有 JMX API 可以杀死这些线程,或者您可以熄火 WAR 以释放线程回到池中。

超时

超时适用于 HTTP 层而不是服务器端。有各种 HTTP 超时,例如:

  • 连接超时 - 建立连接所需的时间。
  • 读取超时 - 因为客户端花费太长时间来读取响应而发生的超时。
  • SO 超时 - 整个操作的套接字超时。

Servlet 对此毫不知情。当写入已关闭的连接时,您应该看到类似“远程主机关闭连接”的错误。

想要避免所有这些问题吗?编写一个能够快速处理请求并尽快返回的 Servlet。那将使您的吞吐量保持高水平,并让用户感到满意。


不存在“SO超时-整个操作的套接字超时”这样的东西。只有连接超时和读取超时,没有其他的。 - user207421
@EJP,经过研究您的评论,我不得不重新定义我对底层SO超时的理解。我一直认为读取超时更加细粒度。我会编辑答案。谢谢。 - Deepak Bala
我希望你所谓的“重新定义我的理解”实际上是指“检查我的事实,而不是胡说八道”。这里还有更多的发明。剩下的超时时间,那些实际存在的,是在TCP层而不是HTTP层,它们适用于双方。像“远程主机关闭连接”这样的错误只存在于你的想象中。我希望你是指“对等方重置连接”,但你总是可以第一次就做对。而关于线程池的整个离题讨论实际上与此无关。 - user207421
剩余的超时时间可以设置为HTTP连接。我并没有暗示它们属于HTTP。当连接被强制关闭时,我不明白为什么这是我的想象,因为它们确实发生了。通过重新定义我的理解,我指的是我的SO-Timeout设置最初是不正确的,直到我阅读了您的评论并再次进行了研究。你声称我“编造事情”最多是令人愉快的,没有留下任何考虑我可能正在纠正一个诚实错误的余地。线程池不是离题。OP想知道它们会发生什么。 - Deepak Bala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接