我有从 http servlet 调用的繁重、耗时的逻辑。当请求超时时会发生什么?servlet 容器会挂起底层的 http 线程吗?还是会继续运行?
2 回答
servlet线程仍在运行,因为超时是客户端行为,唯一的影响是客户端关闭请求的输入流(servlet的输出流),结果可能不会发送到客户端。
它将继续运行,而不会意识到请求请求的客户端可能早已不复存在。
线程池
应用程序服务器通常包含一个有界线程池来服务请求。这些池可用于每个 Web 应用程序,甚至可以针对 servlet/EJB。当您长时间(或永远)运行一个线程时,它会利用池中的一个线程,并且在完成之前永远不会返回该资源。这可能会导致线程池达到其最大大小并最终降低对 Web 应用程序的调用性能。
还有一个无界线程池的概念,其中池可以使用的最大线程数仅受硬件限制。这对于服务器定义的“服务质量”属性可能不是一个好主意,因为无界池会影响整个机器,而不仅仅是导致问题的 WAR / 代码。
卡住的线程
一些应用程序服务器提供了检测这一点并将此类线程标记为STUCK的规定。有可以杀死线程的 JMX api,或者您可以核对 WAR 以将线程释放回池中。
超时
超时适用于 HTTP 层而不是服务器端。这些是各种 HTTP 超时,例如。
- 连接超时- 建立连接所用的时间。
- 读取超时- 由于客户端读取响应时间过长而发生的超时。
SO Timeout - 整个操作的套接字超时。
servlet 不知道这些。写入关闭的连接时,您应该会看到以下错误 -Connection close by remote host
想避免这一切吗?编写一个快速处理您的请求并尽快返回的 servlet。这将保持您的高吞吐量和用户满意。