因为附件服务重启的问题

生产的服务器出现以下现象:

1.API报503,

2.不停的重启

发现是OOM的错误。

作为经验法则,有几种常见的OOM情况。

堆内存溢出。如内存泄漏。

虚拟机栈和本地方法栈溢出。如有无限的递归方法。

JVM内存消耗超过容器限制。

从上面的截图中,可以看出

内存消耗接近100%。

CPU负载峰值少于5个,这应该是FULL-GC的结果。

GC指标相对健康,没有被频繁执行。


因为CPU负载不是很高,所以排除了虚拟机栈和本地方法栈溢出的情况。

package com.controllerimport org.apache.commons.io.FileUtils
import org.springframework.boot.actuate.management.HeapDumpWebEndpoint
import org.springframework.boot.actuate.management.ThreadDumpEndpoint
import org.springframework.core.io.Resource
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.RestController
import java.io.IOException
import java.nio.charset.StandardCharsets
import javax.servlet.http.HttpServletResponse/*** The controller of Monitor****/
@RestController
@RequestMapping
class MonitorController(private val threadDumpEndpoint: ThreadDumpEndpoint?,private val heapDumpWebEndpoint: HeapDumpWebEndpoint?
) {@RequestMapping("jmap")@ResponseBody@Throws(IOException::class)fun jmap(response: HttpServletResponse?): String? {if (this.heapDumpWebEndpoint == null) {return "not existed"}val resource: Resource = this.heapDumpWebEndpoint.heapDump(true).getBody()val bytes: ByteArray = FileUtils.readFileToByteArray(resource.getFile())val delete: Boolean = resource.getFile().delete()return download(response!!, resource.getFilename()!!, bytes, delete.toString())}@GetMapping("jstack")@ResponseBodyfun jstack(response: HttpServletResponse): String? {if (threadDumpEndpoint == null) {return "not existed"}val threads = threadDumpEndpoint.textThreadDump()return download(response, "thread-dump.txt", threads.toByteArray(StandardCharsets.UTF_8), "")}private fun download(response: HttpServletResponse, fileName: String, bytes: ByteArray, value: String): String? {response.characterEncoding = "utf-8"response.contentType = "application/octet-stream"response.addHeader("Content-Length", bytes.size.toString())response.setHeader("Content-Disposition", "attachment; filename=$fileName")try {response.outputStream.use { outputStream ->outputStream.write(bytes)outputStream.flush()return value}} catch (exception: Exception) {return exception.message}}
}

检查JVM的启动配置。

由于堆内存溢出、虚拟机堆栈和本地方法堆栈溢出已经被排除,只剩下JVM内存消耗超过容器限制。让我们先检查一下附件中的JVM启动配置,以验证它。


JVM配置的屏幕截图

从上面的截图中可以看出。

GC使用G1,最大的垃圾年龄是5次(如果一个对象在交换5次后仍然存活,它将被复制到旧gen)。而GC暂停的最大毫秒数为80毫秒。

容器的最大内存限制是2G。

最小和最大的Heap Memory是一样的,都是1.6G左右。

Attachments占用的内存已经达到了容器上限的80%。

得到结论


一旦Attachments被启动,就会请求1.6G的内存,这大约是容器限制的80%,并且会一直占用该内存,而不管它是否真的需要。这就解释了为什么内存消耗几乎是100%。

上面的MAT分析表明,实际使用的内存并不多,这就解释了为什么在高内存占用的情况下,Full GC不会被频繁触发。

假设容器设置的规则是,如果JVM占用的内存超过容器上限的80%,就会被判定为OOM,并试图杀死它,最终会触发重启。这就解释了为什么它在几天内重启了几十次。

所以附件的OOM应该属于JVM内存消耗超过容器限制的情况。

4. 行动


我们使用的是JDK11,我们可以使用一些新的功能,使JVM能够识别容器,并以容器的CPU和内存限制来设置适当的资源,以避免意外地杀死Meza-App。


因此,我们可以尝试

使用参数UseContainerSupport、InitialRAMPercentage、MinRAMPercentage和MaxRAMPercentage来限制内存使用。

取消Xmx、Xmn、UseG1GC、MaxTenuringThreshold和MaxGCPauseMillis等参数,交由JDK11根据容器本身的实际情况来决定。

根据指导原则,将min_replicas从1修改为2。


可以清楚地看到,修改配置后,内存使用量有了明显的下降。请查看以下相关截图。

通过www.DeepL.com/Translator(免费版)翻译

强烈建议将PRD中的最小荚数设置为大于1,否则,一旦遇到严重问题,API将完全无法对外开放,这将严重影响客户体验。


需要定期检查pod的健康状态。如果前端没有遇到 503 错误,我们可能需要更多时间来确定问题。


在使用容器时,我们应该始终使用 UseContainerSupport、InitialRAMPercentage、MinRAMPercentage 和 MaxRAMPercentage 而不是 Xmx & Xmn 来限制内存等资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/24402.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python数据分析-心脏瓣膜手术风险分析与预测

研究背景 人的心脏有四个瓣膜,主动脉银、二尖、肺动脉和三尖源 不管是那一个膜发生了病变,都会导致心脏内的血流受到影响,这就是通常所说的心脏期膜病,很多是需要通过手术的方式进行改善的。随着人口老龄化的加剧,,心…

8. 正则表达式

正则表达式 在处理字符串时,需要查找符合某些复杂规则的字符串,正则表达式就是用于描述这些规则的工具 一、正则表达式语法 行定位符:用来描述字符串的边界 -->用来匹配一整行 符号匹配位置^行的开始$行的结尾 ^tm : 可以匹配行 tm equa…

DevOps 安全集成:从开发到部署,全生命周期安全守护

目录 一、DevOps 安全集成:为什么要做? 二、DevOps 安全集成:如何做? 三、DevOps 安全集成的优势 四、DevOps 安全集成:一些最佳实践 五、DevOps 安全集成:未来展望 六、思考与建议 七、总结 DevOps…

Perl 运算符

Perl 运算符 Perl 是一种功能强大的编程语言,广泛应用于系统管理、网络编程、GUI 创建、数据库访问等众多领域。Perl 的语法灵活,支持多种编程范式,包括过程式、面向对象和函数式编程。在 Perl 中,运算符扮演着重要的角色,它们用于执行各种操作,如算术运算、比较、赋值等…

高质量 HarmonyOS 权限管控流程

高质量 HarmonyOS 权限管控流程 在 HarmonyOS 应用开发过程中,往往会涉及到敏感数据和硬件资源的调动和访问,而这部分的调用就会涉及到管控这部分的知识和内容了。我们需要对它有所了解,才可以在应用开发中提高效率和避免踩坑。 权限管控了…

19、Go Gin框架集成Swagger

介绍: Swagger 支持在 Gin 路由中使用一系列注释来描述 API 的各个方面。以下是一些常用的 Swagger 注释属性,这些属性可以在 Gin 路由的注释中使用: Summary: 路由的简短摘要。Description: 路由的详细描述。Tags: 用于对路由进行分类的标…

跟我学C++高级篇——回调函数及应用

一、回调函数 什么是回调函数?顾名思意,回调函数就是调用方被(被调用方)调用,有点绕口啊。一般的函数调用,都是一方向另一方发起调用,然后得到调用的结果。一般情况下,回调函数通过…

Unity中的CanvasScaler组件讲解

Unity中的CanvasScaler组件是UGUI系统中的一个关键组件,主要用于控制画布的缩放和适配,以确保UI在不同屏幕分辨率下的显示效果一致。以下是关于CanvasScaler组件的详细讲解: 一、CanvasScaler组件的作用 调整UI画布的缩放和分辨率适配&…

数据挖掘--数据仓库与联机分析处理

什么是数据仓库 (面集时非) 面向主题的:围绕某一主题来构建集成的:图片文字杂糅在一起时变的:随时间变化的数据非易失的:硬盘存放,不易丢失 操作数据库系统(OLTP)与数据仓库(OLAP…

MySQL将错乱的水果信息,截取展示为 品名 英文名 价格 三列展示

将错乱的水果信息,截取展示为 品名 英文名 价格 三列展示 idname1苹果Apple72Plum6李子3Pineapple8菠萝4Mango5芒果5龙吐珠5Buddha’sHand6Olive9橄榄7Raspberry4树莓8Apricot5杏子9Grapefruit9柚子10火龙果Dragonfruit911倒挂金钟Hanging6LobsterClaw12巨峰葡萄Co…

AI办公自动化:批量把docx文档转换为txt文本

任务:把docx文档批量转换成txt,首先让deepseek写了一段代码,但是转换失败。用的是最流行的python-docx库来读取docx文档,但是始终无法读取成功,换成pywin32库就解决问题了。 在deepseek中输入提示词: 写一…

「前端+鸿蒙」鸿蒙应用开发-真机运行

在鸿蒙应用开发中,真机运行是验证应用在实际硬件上表现的重要步骤。以下是如何在华为DevEco Studio中配置真机运行的详细步骤,以及相应的示例代码。 快速体验-真机运行 准备工作: 确保您的鸿蒙设备已开启开发者模式,并启用USB调试…

部件库(Widget Factory)

部件库(Widget Factory) 部件库,也被称为Widget Factory,是一个强大的工具,用于创建、存储和管理可重用的软件组件。在本文中,我们将深入探讨部件库的概念、重要性、以及如何在现代软件开发中使用它。 什么是部件库? 部件库是一个集合,其中包含了各种预先构建的软件…

c++ 简单的日志类 CCLog

此日志类,简单地实现了向标准输出控制台和文件输出日志信息的功能,并能在这两者之间进行切换输出,满足输出日志的不同需求。 代码如下: /** CCLog.h* c_common_codes** Created by xichen on 12-1-12.* Copyright 2012 cc_te…

40.任务调度线程池

Timer(废弃) 在任务调度线程池功能加入之前,可以使用java.util.Timer来实现定时功能,Timer优点在于简单易用,缺点是由于所有的任务都是由同一个线程来调度,因此所有的任务都是串行执行,同一时间只能有一个任务在执行,前一个任务的延迟和异常都将会影响之后的任务。 T…

【背包-BM70 兑换零钱(一)】

题目 BM70 兑换零钱(一) 描述 给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。 如果无解,…

docker 命令 ps,inspect,top,logs详解

docker常用命令教程-4 docker ps docker ps 命令用于列出当前正在运行的容器。默认情况下,它只显示正在运行的容器,但你可以使用 -a 或 --all 选项来显示所有容器(包括已停止的容器)。 常用的选项和示例: -a 或 --…

【C语言题解】1、写一个宏来计算结构体中某成员相对于首地址的偏移量;2、写一个宏来交换一个整数二进制的奇偶位

🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🌈感谢大家的阅读、点赞、收藏和关注 💕希望大家喜欢我本次的讲解💕 目录👑 1、写一个宏,计算结构体中某变量相对于首地址的偏…

UE4获取动画序列资产的动画时长

谢谢”朝闻道“大佬的指点~

(UE4.26)UE4的FArchive序列化入门

前言 序列化(Serialize)和反序列化(UnSerialize)是程序领域常见的概念。对于这两个词汇我理解的是 序列化(Serialize): 变量值(int, float, string等基本类型, 或者Array,Map,或者更复杂的复合体)存储为一个文件(二进制流, 二进制文件, json, xml等格式…