Spring Boot 微服务在 docker-swarm 中消耗大量内存

我有一些docker swarm 容器在Azure上的Ubuntu 16.04.4 LTS实例上运行。容器正在运行 Java Spring Boot 和 Netflix OSS 应用程序,如 Eureka、Ribbon、Gateway 等应用程序。我观察到我的容器占用了大量内存,尽管服务只是 REST 端点。

我试图通过像下面这样传递 Java VM 参数来限制内存消耗,但这无济于事,即使之后大小也没有改变。

请注意下面我在这里使用的配置,

Java 版本:Java 8 高山

内核版本:4.15.0-1023-azure

操作系统:Ubuntu 16.04.4 LTS

操作系统类型:linux

架构:x86_64

CPU:32

总内存:125.9GiB

之后的内存占用 docker stats

http://img1.mukewang.com/618cc9e90001092d25340150.jpg

Java VM 参数,

docker service create --name xxxxxx-service --replicas 1 --network overnet 127.0.0.1:5000/xxxxxx-service --env JAVA_OPTS="-Xms16m -Xmx32m -XX:MaxMetaspaceSize=48m -XX:CompressedClassSpaceSize=8m -Xss256k -Xmn8m -XX:InitialCodeCacheSize=4m -XX:ReservedCodeCacheSize=8m -XX:MaxDirectMemorySize=16m -XX:+UseCGroupMemoryLimitForHeap -XX:-ShrinkHeapInSteps -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=70"

我也尝试查看每个容器中的应用程序日志文件,但找不到任何与内存相关的错误。我还尝试限制容器资源。但这对我也不起作用。

有什么线索可以解决这个繁重的内存问题吗?


蓝山帝景
浏览 340回答 3
3回答

叮当猫咪

您可以通过使用诸如visualvm 或jprofiler 之类的分析器来解决此问题,它们会向您显示分配了内存的位置(哪些类型的对象等)。如果可能,您不应该在生产系统上使用它,因为分析可能会占用大量 CPU。

莫回无

了解我过去使用过的更多信息的另一种方法是使用AspectJ 的加载时间编织来添加特殊代码,将内存信息添加到您的日志文件中。这也会减慢您的系统速度,但是当您的方面已经被写入时,不如使用配置文件。如果可能的话,分析将是首选 - 如果不是,AspectJ 加载时间编织可能会有所帮助。

翻阅古今

您可以尝试启用执行器并将内存消耗值与 docker stats 生成的值进行比较。要启用执行器,您可以在 pom.xml 文件中添加以下依赖项。<dependency>&nbsp; &nbsp; <groupId>org.springframework.boot</groupId>&nbsp; &nbsp; <artifactId>spring-boot-starter-actuator</artifactId></dependency>我通常使用 HAL 浏览器来监控应用程序并使用执行器端点。您可以使用以下 maven 依赖项添加它。<dependency>&nbsp; &nbsp; <groupId>org.springframework.data</groupId>&nbsp; &nbsp; <artifactId>spring-data-rest-hal-browser</artifactId></dependency>在 HAL 浏览器中,您可以尝试使用/metrics应用程序的端点。示例输出如下所示。{&nbsp; &nbsp; "mem" : 193024,&nbsp; &nbsp; "mem.free" : 87693,&nbsp; &nbsp; "processors" : 4,&nbsp; &nbsp; "instance.uptime" : 305027,&nbsp; &nbsp; "uptime" : 307077,&nbsp; &nbsp; "systemload.average" : 0.11,&nbsp; &nbsp; "heap.committed" : 193024,&nbsp; &nbsp; "heap.init" : 124928,&nbsp; &nbsp; "heap.used" : 105330,&nbsp; &nbsp; "heap" : 1764352,&nbsp; &nbsp; "threads.peak" : 22,&nbsp; &nbsp; "threads.daemon" : 19,&nbsp; &nbsp; "threads" : 22,&nbsp; &nbsp; "classes" : 5819,&nbsp; &nbsp; "classes.loaded" : 5819,&nbsp; &nbsp; "classes.unloaded" : 0,&nbsp; &nbsp; "gc.ps_scavenge.count" : 7,&nbsp; &nbsp; "gc.ps_scavenge.time" : 54,&nbsp; &nbsp; "gc.ps_marksweep.count" : 1,&nbsp; &nbsp; "gc.ps_marksweep.time" : 44,&nbsp; &nbsp; "httpsessions.max" : -1,&nbsp; &nbsp; "httpsessions.active" : 0,&nbsp; &nbsp; "counter.status.200.root" : 1,&nbsp; &nbsp; "gauge.response.root" : 37.0}通过这种方式,您可以监控应用程序的内存性能并了解应用程序实际消耗了多少内存。如果这与 docker 生成的报告类似,那么这就是您的代码的问题。但是我必须声明,执行器的使用不是生产友好的,因为它本身具有显着的资源开销。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java