【问题标题】:When does servlet release its threadservlet什么时候释放它的线程
【发布时间】:2013-03-23 00:26:29
【问题描述】:

假设没有保持活动状态,当 servlet 容器充当独立服务器时,我假设 servlet 的线程在整个响应发送到客户端(例如 Web 浏览器)之前不会被释放。这是一个正确的假设吗?

但是如果 servlet 位于像 Nginx 这样的反向代理之后会发生什么?一旦响应被传递到 Nginx,线程是被释放,还是在响应被发送到它的最终客户端(比如浏览器)之前被保留?

更新:让我试着把它说得更清楚一点。

响应从 servlet 发送到像 nginx 这样的代理只需要几毫秒(比如 2 毫秒)。但最终响应从 nginx 发送到浏览器可能需要额外的 80 毫秒(左右)时间。一旦响应发送到 nginx,servlet 是否释放线程/流,或者 servlet 是否保留它们直到响应发送到浏览器(即整个 80 毫秒)

【问题讨论】:

  • 容器不知道它在代理后面,所以这没有区别。通常容器使用线程池,因此线程被无限期地保留。
  • 但是 servlet 的输出是否首先进入 nginx 的缓冲区/流?此时 servlet 可以认为响应已完全发送,因此 servlet 关闭流并将线程释放回池中。 nginx 和 servlet 之间的通信只需要几毫秒,而最终响应到达浏览器需要(比如说)80 英里秒。 servlet 是一直持有连接/线程,还是只是发送到 Nginx 的时间。

标签: java multithreading servlets nginx


【解决方案1】:

问题:我假设 servlet 的线程在整个响应发送到客户端(比如网络浏览器)之前不会被释放。这是一个正确的假设吗?

回答:不,这是错误的。 Servlet 容器只会将内容写入套接字并返回。不保证 write() 方法的返回会确保响应已经到达客户端。

问题:线程是在响应传递到 Nginx 后释放,还是在响应发送到最终客户端(例如浏览器)之前保持线程?

Ans: 当 Nginx 落后时,Servlet 容器的客户端就是 Nginx。它不知道实际的远程客户端。因此,一旦响应写入 Nginx,线程就会被释放。

【讨论】:

    【解决方案2】:

    服务器容器无法向客户端发送响应将触发将由容器处理的异常。您可以通过 try catch finally(使用 close())将写入包含到输出流或写入器,但您不需要,容器将管理,包括将线程返回到池中。 问候 S

    【讨论】:

    • 我不太确定我是否理解您的回答。是的,它将由容器管理,我只是想知道“何时”线程/流被释放/关闭。特别是当它落后于像 nginx 这样的东西时。
    • 我查看了 nginx 缓冲区配置。如果 nginx 的缓冲区足够大以容纳整个响应流,则应用程序服务器将立即关闭,否则它将在整个流被刷新或发生超时时关闭。您必须在应用程序服务器上设置日志机制并衡量不同的可能性和各自的时间。
    【解决方案3】:

    servlet 看不到网络。根据specifications 处理了2个对象:一个Request和一个要填写的Response(在HTTP的情况下,这意味着一个HTTPRequest和一个HTTPResponse)。它应处理请求对象内的请求数据,并写入响应对象中的缓冲区。一旦该内容被 servlet提交,容器可能会进行一些后处理(使用过滤器)并将其传输回客户端。

    一旦对请求处理方法的调用完成,servlet 线程就会自然地返回到池中(如果方法需要做进一步的工作,这可能发生在有效负载被发送回客户端之后。

    请注意,由于 servlet 看不到网络并且只关心单个请求,因此 http 连接的状态(保持活动或关闭)与 servlet 生命周期无关;多个 servlet 可以处理在单个连接中流水线化的不同请求。有关相关问题,请参阅此 question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多