【问题标题】:How to handle many slow connections如何处理许多慢速连接
【发布时间】:2016-12-25 16:59:01
【问题描述】:

我们的网络应用程序的吞吐量似乎受到慢速连接的限制。在负载测试中,我们轻松实现了大约 5000 个请求/秒。但在实践中,我们的最大请求速度约为 1000 个请求/秒。服务器并没有真正承受严重的负载,无论是 IO 还是 CPU 方面。这同样适用于数据库。主要区别似乎是大多数工作线程会因无法足够快地接受响应的客户端(通常响应大小为几 MB)而减慢。

我们几乎没有任何静态资源。问题在于动态生成的内容。它是用 Spring 框架实现的。但我认为对于任何其他基于 servlet 的实现来说都不会有所不同。

那么我们有哪些提高吞吐量的选择?是否有某种可用的缓存可以快速吸收响应,释放工作线程,然后以它们的速度异步将其交付给客户端?

我们不希望增加处理线程的数量,因为它们会在大部分处理过程中保持数据库连接打开。我们确实在寻找一种可以让少量工作线程全速工作的解决方案。

【问题讨论】:

  • 我找到了关于您的问题的描述以及解决方案的方向here。 nginx“反向代理”听起来promising。如果它有效,请在回答您自己的问题时告诉我们,我可能有一天也需要它。
  • 感谢您的提示。是的,启用缓冲的 nginx 反向代理似乎是我们正在寻找的。我们需要一些时间来配置它并验证它在现实环境中增加了我们的吞吐量。

标签: java tomcat servlets tomcat8


【解决方案1】:

我建议您使用 gzip 等标准技术进行响应。

第二种是在Spring MVC中使用异步处理。请参阅Making a Controller Method Asynchronous 了解更多信息。

【讨论】:

  • 我们已经在对可压缩数据使用压缩。我对异步控制器的理解是它们解决了一个不同的问题:如果您与客户端的 HTTP 连接空闲,它们会有所帮助,因为它是事件驱动的服务器推送,或者因为服务器必须将请求转发到另一个系统并等待很长时间。在我们的例子中,客户是瓶颈。你能描述一下它是如何应用于这个案例的吗?它真的会缓冲输出直到客户端吸收它吗?
  • 使用异步控制器可以实现具有给定线程池大小和队列机制的 AsyncTaskExecutor,而控制器仍将处理新请求。但如果我理解正确,您应该查看架构:1)集群应用程序,2)替换输出格式以减少网络负载,3)分块输出,4)代理缓存(如 nginx)等等。否则不可能输出超过客户端实际处理能力的数据。
  • 感谢您的想法。仔细观察,nginx 作为带有缓冲的反向代理看起来像是一个有效的选项(正如 vanOekel 提出的那样)。集群将需要增加数据库连接的总数,考虑到服务器有空闲的 CPU 和 IO 容量,这似乎是一种浪费。我们没有替换输出格式的选项。并且所有连接都已经使用了分块输出。
  • 如果架构如下,则没有额外的数据库连接:集群化的“前端”在多个节点上处理来自客户端的请求,业务特定处理称为“后端”在单个节点上节点(如果你想要这个),例如,Apache Kafka 作为“前”和“后”之间的数据总线是必需的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 2017-07-13
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2021-01-09
相关资源
最近更新 更多