【问题标题】:Spring boot services are consuming too much memorySpring Boot 服务消耗太多内存
【发布时间】:2020-01-06 02:04:11
【问题描述】:

我们正在开发一个基于微服务架构和Spring Boot技术的系统。

一切正常,我们喜欢它,但我们担心每项服务消耗的资源。

我们的系统分布在 8-12 个微服务中,每个微服务至少使用大约 550MB 的 RAM。

我们试图通过系统变量来限制资源,但性能严重下降,因此物理上限制资源不是一种选择。

mem_limit: 200m
memswap_limit: 400m

关于这个,我想知道:

用spring boot实现的服务消耗这么多内存是正常的吗? 我们可以做些什么来优化它?

配置:

我们目前使用 CentOS 7.5 作为运行 docker 的主机操作系统。

openjdk:11

【问题讨论】:

  • 每项服务都是自己的世界。你在缓存数据吗?那是在堆上吗?还是堆外?哪个服务被调用很多,哪个不是?您正在使用什么 GC 算法(可能是 G1?)。您可能需要使用 VisualVM 或其他工具来运行每个服务,这些工具允许您查看内存并弄清楚如何处理每个服务。一个不经常调用的小型 Spring Boot 应用程序(3-4 个并发请求)可以使用 192MB 的 RAM 运行,但这取决于许多因素。做一个内存转储,看看到底是什么在消耗内存。

标签: spring-boot docker


【解决方案1】:

这很正常。我们遇到了同样的问题。经过研究,我想出了以下解决方案:

严格的内存限制导致之前没有错误的更多错误(容器和 Java 堆空间中的严格内存限制)

基本思想是为服务提供更多内存,然后再在 ram 中物理可用。要处理最终可能导致内存问题的峰值,您可以在主机系统上使用交换。从我的角度来看,您不需要在 docker 容器内进行一些交换内存限制。当内存非常满时,主机系统的内核会管理它。

Lat 说您有 32GB 的 RAM 和 16GB 的 SWAP。您可以分配内存限制(docker 和 jvm 堆空间),总和超过 32GB 但小于 32GB+16GB(为了安全起见)。这种过度配置仅用于处理服务的负载偷窥。这些限制仅用于在出现问题并且只有一项服务失败而不是整个系统失败时快速失败。

您可以调整一个 swappiness 值以防止过多的交换,如果您将 -XX:MaxHeapFreeRatio 从默认值 70 降低,您可以告诉 jvm 更快地将分配的堆空间释放回操作系统。

但从长远来看,您需要一些东西来监控所有服务的内存使用情况(“prometheus grafana”?)并重新分配内存限制以适应您的物理限制。

【讨论】:

猜你喜欢
  • 2019-01-16
  • 2020-03-19
  • 2016-05-03
  • 2018-05-05
  • 2020-04-16
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多