针对高 CPU/memory 工作负载优化 Spring 引导后端

Optimise a Spring Boot backend for high CPU/memory workloads

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

我预计后端会做一些繁重的 ETL 工作,这对内存和 CPU 端来说会很繁重。同时,它不需要扩展来为许多并发请求提供服务——它只真正需要为启动和管理作业的请求提供服务,这些作业将由与其交互的单个用户调用。

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

目前的想法:

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

如果您有很长的 运行 后台任务,我会将工作卸载到 threadpool 并将最大线程数设置为您系统中 CPU 的线程数.还要在执行程序的队列上设置最大容量,这样您就不会因太多未决工作而使它超载。

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

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

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

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

附带说明 Spring 生态系统中还有另一个项目 - Spring Batch 使用大量此类优化技术,适用于 ETL 类型作业的批处理。您可以阅读一些技巧 here