【问题标题】:Optimise a Spring Boot backend for high CPU/memory workloads针对高 CPU/内存工作负载优化 Spring Boot 后端
【发布时间】:2021-08-10 23:11:14
【问题描述】:

我正在运行一个 Spring Boot 应用程序,它充当前端 Javascript 应用程序的后端。前端作为静态资源提供给客户端,后端提供来自它的 API 请求。该应用程序最初设计为在本地运行,但应以允许轻松移植到云原生解决方案的方式构建。

我希望后端能够完成一些繁重的 ETL 工作,这在内存和 CPU 方面会很繁重。同时,它不需要扩展以服务许多并发请求 - 它只需要服务启动和管理作业的请求,这些作业将由与其交互的单个用户调用。

我可以调整哪些参数以针对此类部署进行微调?

目前的想法:

  • server.tomcat.max-threads 减少到一位数以最小化请求线程池的占用空间,因为我预计不会同时处理超过一到两个
  • 对数据库连接池执行相同操作
  • 在启动 JAR 时微调 XmsXmx

对于如何确保 Java 应用程序在系统上占用尽可能大的空间以及我可以调整的 Spring Boot 特定参数的任何其他见解,我将不胜感激。谢谢。

【问题讨论】:

  • 这个问题不够集中,可能会引起固执己见的回答。因此,我认为,这对 SO 来说是题外话。这是一个问答平台,而不是讨论论坛或邮件列表。
  • 应用运行后,您可以尝试调整垃圾收集设置,看看它如何影响您的性能。这是一篇关于 gc 调优的有用博客文章:blog.gceasy.io/2020/06/02/simple-effective-g1-gc-tuning-tips
  • 我同意@kriegaex 这是一个非常广泛的问题。似乎是什么问题(具有长期运行的业务逻辑、webserver/servlet 容器、数据库连接池、JVM)?为什么你认为它需要微调?您尝试了哪些方法(分析、指标收集、负载测试等)来缩小可能存在的瓶颈?

标签: java spring-boot tomcat resources etl


【解决方案1】:

如果您有长时间运行的后台任务,我会卸载到 threadpool 工作并将最大线程数设置为系统中的 CPU 数。还要设置执行器队列的最大容量,这样您就不会因为太多待处理的工作而使其超载。

卸载到不同的线程将确保容器的线程保持可用,并且您最终不会得到一个完全无响应的系统。

您对最大堆大小和连接池的建议是有效的。

【讨论】:

  • 不错的方法,我认为另一种有用的方法是将工作负载排队到像 RabbitMQ 这样的消息传递系统中,这样您就可以水平升级消费者以根据您的需要执行
【解决方案2】:

通常,优化技术与任何基于 Java 的应用程序相似,因为您的处理是一种 ETL 类型的处理,其中吞吐量比单个请求延迟更重要。

如果任务是典型的 ETL - 与 IO 密集型的提取和加载相比,转换通常更耗费 CPU。所以我的第一个建议是分析您的应用程序以了解典型的 CPU/Mem 使用模式。如果它在 IO 上花费更多时间,那么您可以使用比 CPU 内核更多的处理线程,因此您可以对其进行调整。还要记住,如果内存压力太大,那么垃圾收集器也会消耗大量 CPU,因此最大内存设置也很重要。您可以在您的应用程序中启用 GC 日志作为使用工具,如 this 以轻松分析 GC 模式。您可以尝试更适合高吞吐量的 ParallelGC 算法 以稍高的暂停时间为代价。通常,如果您在提取和加载阶段有大量数据要与之交互,您通常倾向于使用流/缓冲技术来减少内存占用。一个例子是在与数据库交互的同时处理大型结果集时使用游标。同样,如果加载阶段涉及与大文件的交互,您可以使用并行处理。那么但是所有这些都需要实验来验证。

另一方面,Spring 生态系统中还有另一个项目 - Spring Batch,它使用了许多适合 ETL 类型作业批处理的此类优化技术。你可以阅读一些技术here

【讨论】:

    猜你喜欢
    • 2015-09-23
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多