【问题标题】:tomcat Java NIO with concurrent slow TCP client connections具有并发慢速 TCP 客户端连接的 tomcat Java NIO
【发布时间】:2016-08-28 10:32:53
【问题描述】:

我的不善言辞

没有蔚来:
对于每个 keepAlive 连接,服务器继续阻塞一个线程。

与蔚来:
这个连接器有几个轮询线程,用于为所有连接的用户保持连接活动,同时只要数据(新的 HTTP 请求)可用,就会调用工作线程

现在: 如果我有一个简单的 servlet,它会向客户端(浏览器)返回一个 100 KB 的字符串。

....
String HunderdKBString = "reallylongstring"
PrintWriter out = response.getWriter();
out.println(HunderdKBString);
....

如果连接了 1 KB 连接的客户端,则接收字符串大约需要 100 秒。
那么是不是java线程会被阻塞100秒左右呢?

TCP 缓冲区、Java OutputStreamWriter 或其他缓冲区如何影响线程阻塞时间?

PS:在 centos 7 中使用 apache-tomcat-8.0.24 和 oracle JDK 1.7。

编辑:如前所述,线程确实被阻塞,缓冲区可以减少线程阻塞时间。如何优化 tomcat/OS 以通过使用这些缓冲区来减少线程阻塞时间?

如果tomcat由于连接了许多慢速连接客户端而导致线程不足,如何在生产环境中检测到?

【问题讨论】:

  • 关于 NIO 的讨论没有意义。在 Tomcat 容器中,您无法选择切换 IO 技术。您必须使用 Tomcat 为您提供的同步 Writer 实例。但我同意许多慢速连接可能是一个严重的现实问题。您期望有多少并发连接? 100? 1000? 10000? 100000?
  • @Codo 我们在具有峰值负载行为的站点上工作。突然 500 个客户端可以连接。这可能转换为 500*(来自浏览器的 4 个 TCP 连接)= 2000 .. 是的,很多可能很慢..
  • 在2000个并行连接的情况下,最务实的解决方案是将Tomat工作线程的数量增加到2000个(甚至更多)。今天的服务器应该可以轻松处理这么多线程。不过,您可能需要为 Tomcat 分配足够的内存。如果我们谈论的是 100,000 个连接,情况会有所不同。
  • 另一个选项 - 假设您的响应不包含任何用户或会话特定数据,因此是可缓存的 - 是将 nginx 作为缓存放在 Tomcat 前面。 nginx 可以选择立即消费整个响应并以给定的慢速转发给客户端。
  • 如果您的响应不可缓存,nginx 甚至可能会工作。看看Using Buffers to Free Up Backend Servers

标签: java http tomcat servlets tcp


【解决方案1】:

那么是不是java线程会被阻塞100秒左右?

是的。

TCP 缓冲区、Java OutputStream 或 Writer 或其他缓冲区如何影响线程阻塞时间?

如果缓冲区大到足以容纳发送的数据,发送线程不会阻塞。

【讨论】:

  • 能否请您指出有关如何优化 tomcat/OS 以通过增加这些不同类型的缓冲区来减少线程阻塞时间的资源
  • 我不同意@EJP 的第二条陈述:缓冲区只有在操作系统级别才有帮助。 OutputStream 或 Writer 类中的缓冲区无济于事,因为一旦 Tomcat 尝试刷新所有未完成的数据,它们仍会阻塞。
  • 与其开始修补缓冲区,不如将请求超时减少到可接受的水平。如果用户长时间占用线程并导致饥饿,那么及时杀死这些用户的线程将解决您的问题。无论您的问题是由用户引起的,还是您所提供的文件太大,操作系统方面都可能几乎没有优化。更仔细地查看服务器的配置。
  • @Codo 我的第二个陈述是正确的。我没有说缓冲区“帮助”,从阻塞的角度来看,你在谈论哪个缓冲区没有区别。一旦所有缓冲区都满了,发送就会阻塞。
猜你喜欢
  • 1970-01-01
  • 2010-10-25
  • 2010-11-18
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 2014-08-25
相关资源
最近更新 更多