SAP BTP云上一个JVM与DB Connection纠缠的案例

图片

前言

最近在CF (Cloud Foundry) 云平台上遇到一个比较经典的案例。因为牵扯到JVM (app进程)与数据库连接两大块,稍有不慎,很容易引起不快。

在云环境下,有时候相互扯皮的事蛮多。如果是DB的问题,就会找DB相关部门。关键是如何自证。涉及到职场生存法则,大家都不愿意去背锅,谁背锅,意味着谁要担责。

下边我们看看这个案例。

现场

某一个微服务的Java应用,在部署到云环境下,大概过了几个小时以后,就频繁的宕掉,自动重启,一会儿又宕掉。DevOPS马上发警告邮件,并且给出了一些error message, 甚至相关的callstack也给出来了。

java.sql.SQLTransientConnectionException: HikariPool-******* - Connection is not available, request timed out after 5001ms.,  at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:696),  at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197),  at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162),  at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100),  at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122),  at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38),  at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:108),  at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:138),  at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:276),  at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:284),  at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:246),  at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:83),  at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:164),  at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:421),  at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400),  at 

就这咋一看,就是connection用完了,拿不到连接了。DB相关人员开始就有点紧张了。难道是DB出问题了?

于是他们单独给DBOps那边开了个ticket,让DBOps直接上AWS PG实例里头查看,一顿查,发现数据库活的好好的呢,在那个时间段,连接数也都还正常。这样的话,他们肯定不会背这锅。

微服务这边,在得知这些结果以后,感觉就有些不太妙了。于是再重新再去查监控:

图片

总数确实也还在那里。单独针对那众目标微服务,再看看细化的情况:

图片

到这里,一看,200个连接瞬间被击垮。看到这里,基本上也就知道,与数据库大概率没什么关系了。应该是应用层出了什么故障了。

什么原因会导致数据库正常但是连接拿不到(不断超时、我们这里是默认5秒还拿不到连接,就算超时,app会自动重启)?

紧接着我们兵分两路:

1、再找到微服务对应的DynaTrace监控

有一个重大发现:

图片

死掉的那一段时间,JVM的Metaspace那一段200MB,全部耗光。但是因为没有CF平台上没有明显的OOM报错,反而容易骗过大家。

2、再细看一下平台那边的Kibana LOG相关细节:

虽然没有:OOM之类的错误提示,却发现有若干下边这样的log:

[33281.379s][error][jvmti] Posting Resource Exhausted event: Metaspace
[33281.379s][error][jvmti] Posting Resource Exhausted event: Metaspace
Resource exhaustion event....
.......

这两条就足以印证jvm的配置参数Metaspace的大小不够,导致最后的问题。

解决方法:将原来的200M调整到300M或250M,就彻底平息了这次事故。

总结:

有的时候,问题不是孤立存在的,从各个层面进行分析,逐个排错,最后还是能找到出问题的原因。如何规避此类事件再次发生,只能进一步加强监控。

以上例为例,因为缺乏对应用层DB Pool的监控预警,比如它很快涨到200,在那一会儿,应该直接就有预警。另一块,针对metaspace耗尽之前也缺乏预警。如果到了90%左右发出预警,那我们仍然有机会重新调整参数,再次部署,一样可以避免问题。

至于引起metaspace上涨的一个主要原因,是因为新部署的app, 增加了另外几个库(合计有几十兆),从而让类的元数据所需空间增加了不少。开发人员平时也很少关注这一块。加起来,刚好快到边界,又没到边界,随着动态类的加载,慢慢又涨了一点,最终导致超标。

关于jvm参数及高优,又是一个非常大的话题:

参考:

https://cloud.tencent.com/developer/article/1408827[1]

https://poonamparhar.github.io/understanding-metaspace-gc-logs[2]

What is Compressed Class Space?[3]

[How to Handle Java Lang OutOfMemoryError Exceptions[4]](https://sematext.com/blog/java-lang-outofmemoryerror/)

图片

上边这张图也能说明一下总的计算方法。Metaspace属于Non-heap的空间。也就是说,在计算总的开销时,它增加了,Java heap那部分就得减小。

JBP_CONFIG_SAP_MACHINE_JRE [memory_calculator_v2: {headroom: 5}]
JBP_CONFIG_SAP_MACHINE_JRE: [memory_calculator_v2: {stack_threads: 600, headroom: 5}]
JBP_CONFIG_JAVA_OPTS      [ java_opts: '-Xss512K -XX:ReservedCodeCacheSize=220M -XX:MaxMetaspaceSize=200M -XX:MaxDirectMemorySize=256M -XX:+DisableExplicitGC -XX:+UseG1GC ' ]
上边用的是SAP自己的JVM(使用OpenJDK结果也一样): SAP在给定4096M总的容器内存时:
4096 - 220 - 200 - 256 - 0.05 * 4096 - 0.5 * 250 = 3090.2 M = 3164364K当stack_threads调为600时,-Xmx2985164K
4096 - 220 - 200 - 256 - 0.05 * 4096 - 0.5 * 600 = 2915.2 M = 2985164K

围绕的公式就是:

MaxHeapSize = 总内存 - CodeCache - MetaspaceSize- DirectMemory - headroom/100 * 总内存 - Xss * Threadcount。(默认线程数是250)

headroom是预留给容器的本地内存的百分比。

这个公式通常也不见于官方文档,属于平台自己控制的。有了这个公式,就可以自己进行精准拿捏了。

还有一些jvm命令行,可以ssh到container内部执行,进行诊断,如:

1、jps -lvm

app/META-INF/.sap_java_buildpack/sap_machine_jre/bin/jps -lvm
1504 jdk.jcmd/sun.tools.jps.Jps -lvm -Dapplication.home=/home/vcap/app/META-INF/.sap_java_buildpack/sap_machine_jre -Xms8m -Djdk.module.main=jdk.jcmd
7 org.springframework.boot.loader.JarLauncher -Xmx2985164K -Xss512K -XX:ReservedCodeCacheSize=220M -XX:MaxMetaspaceSize=200M -XX:MaxDirectMemorySize=256M -XX:+DisableExplicitGC -XX:+UseG1GC -XX:-UseCompressedClassPointers -Djava.io.tmpdir=/home/vcap/tmp -Dlog4j2.formatMsgNoLookups=true -XX:+UseContainerCpuShares -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n,onjcmd=y -agentpath:META-INF/.sap_java_buildpack/jvm_kill/jvmkill-1.16.0.RELEASE-trusty.so=printHeapHistogram=1 -XX:ErrorFile= -Dsun.net.inetaddr.ttl=0 -Dsun.net.inetaddr.negative.ttl=0

2、jcmdVM.flags

vcap@ade456f6-f29d-4e37-7b99-0360:~$ app/META-INF/.sap_java_buildpack/sap_machine_jre/bin/jcmd 7 VM.flags
7:
-XX:CICompilerCount=2 -XX:ConcGCThreads=1 -XX:+DisableExplicitGC -XX:ErrorFile= -XX:G1ConcRefinementThreads=1 -XX:G1HeapRegionSize=1048576 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=69206016 -XX:MarkStackSize=4194304 -XX:MaxDirectMemorySize=268435456 -XX:MaxHeapSize=3057647616 -XX:MaxMetaspaceSize=209715200 -XX:MaxNewSize=1833959424 -XX:MinHeapDeltaBytes=1048576 -XX:NonProfiledCodeHeapSize=0 -XX:ProfiledCodeHeapSize=0 -XX:ReservedCodeCacheSize=230686720 -XX:ThreadStackSize=512 -XX:-UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseContainerCpuShares -XX:+UseG1GC 

3、jcmdGC.heap_info

e456f6-f29d-4e37-7b99-0360:~$ app/META-INF/.sap_java_buildpack/sap_machine_jre/bin/jcmd 7 GC.heap_info
7:garbage-first heap   total 1166336K, used 204288K [0x0000000749c00000, 0x0000000800000000)region size 1024K, 113 young (115712K), 18 survivors (18432K)Metaspace       used 116011K, capacity 117599K, committed 117704K, reserved 118784K

在云环境下,PG的稳定性还是很牛气的。稳如老狗一点也不为过,除了表膨胀、空间肿胀等需要来加看管,很大一部分云平台都给你扛过去了。当然,常规的性能优化与调整也是必要的,应用层开发人员配合DBA,总能找到比较舒服的解决方案。

参考资料

[1]https://cloud.tencent.com/developer/article/1408827: https://cloud.tencent.com/developer/article/1408827

[2]https://poonamparhar.github.io/understanding-metaspace-gc-logs: https://poonamparhar.github.io/understanding-metaspace-gc-logs/

[3]What is Compressed Class Space?: https://stuefe.de/posts/metaspace/what-is-compressed-class-space/

[4][How to Handle Java Lang OutOfMemoryError Exceptions: https://sematext.com/blog/java-lang-outofmemoryerror/

图片

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

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

相关文章

DDos系列攻击原理与防御原理

七层防御体系 静态过滤 命中黑名单 对确定是攻击的流量直接加入黑名单(源地址命中黑名单直接丢弃,缺乏机动性和扩展性) 畸形报文过滤 畸形报文攻击 TCP包含多个标记位,排列组合有规律 • 现象:TCP标记位全为1 …

docker:在ubuntu中运行docker容器

前言 1 本笔记本电脑运行的ubuntu20.04系统 2 docker运行在ubuntu20.04系统 3 docker镜像使用的是ubuntu18.04,这样拉的 docker pull ubuntu:18.04 4 docker容器中运行的是ubuntu18.04的系统,嗯就是严谨 5 这纯粹是学习笔记,实际上没啥价值。…

文件的输入与输出(史上最全)

文件的输入与输出 一个文件是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个流。 从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据&#xf…

指纹浏览器是什么?有哪些好用的推荐?

在网络世界中,保护您的在线隐私和安全非常重要。反检测浏览器是专门为此诞生的工具,旨在通过更改浏览器指纹来帮助您做到这一点,它们使网站、广告商和其他人很难跟踪您的在线行为。 一、什么是反检测浏览器? 您是否想过网站如何检…

C++万物起源:类与对象(二)

一、类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗? 并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员 函数。 默认成员函数:用户没有显式实现,…

动态规划算法及Java实例

动态规划算法的基本概念 动态规划算法是一种解决复杂问题的有效方法,它通过将大问题分解为小问题,然后逐个解决这些小问题,最终通过组合小问题的解来得到大问题的解。这种方法的特点是充分利用了问题的重叠子问题和最优子结构的特性&#xf…

篮球论坛系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文(设计)学生选题参考合集推荐收藏(包含Springboot、jsp、ssmvue等技术项目合集) 目录 1. …

Linux根据时间删除文件或目录

《liunx根据时间删除文件》和 《Linux 根据时间删除文件或者目录》已经讲述了根据时间删除文件或目录的方法。 下面我做一些补充,讲述一个具体例子。以删除/home目录下的文件为例。 首先通过命令: ls -l --time-style"%Y-%m-%d %H:%M:%S"…

Redis、Mysql双写情况下,如何保证数据一致

Redis、Mysql双写情况下,如何保证数据一致 场景谈谈数据一致性三个经典的缓存模式Cache-Aside Pattern读流程写流程 Read-Through/Write-Through(读写穿透)Write behind (异步缓存写入) 操作缓存的时候,删除…

【tensorflow框架神经网络实现鸢尾花分类】

文章目录 1、数据获取2、数据集构建3、模型的训练验证可视化训练过程 1、数据获取 从sklearn中获取鸢尾花数据,并合并处理 from sklearn.datasets import load_iris import pandas as pdx_data load_iris().data y_data load_iris().targetx_data pd.DataFrame…

git泄露

git泄露 CTFHub技能树-Web-信息泄露-备份文件下载 当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。 工具GitHack使用:python2 GitHack.py URL地址/.git/ git命令…

怎样才能把重建大师的空三导进去CC?

导出空三文件xml两者都是通用的,cc和photoscan都可以兼容。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件,输入倾斜照片,激光点云,POS信息及像控点,输出高精度彩色网格模型,可一键…

ros2相关代码记录

1.ros2概述 ROS2(Robot Operating System 2)是一个用于机器人应用程序的开源软件框架。它是ROS(Robot Operating System)的下一代版本,旨在改进和扩展原始ROS的特性,以适应更广泛的机器人应用场景和需求。…

Unity 实现鼠标左键进行射击

发射脚本实现思路 分析 确定用户交互方式:通过鼠标左键点击发射子弹。确定子弹发射逻辑:每次点击后有一定时间间隔才能再次发射。确定子弹发射源和方向:子弹从枪口(Transform)位置发射,沿枪口方向前进。 变…

Qt扫盲-QAssisant 集成其他qch帮助文档

QAssisant 集成其他qch帮助文档 一、概述二、Cmake qch例子1. 下载 Cmake.qch2. 添加qch1. 直接放置于Qt 帮助的目录下2. 在 QAssisant中添加 一、概述 QAssisant是一个很好的帮助文档,他提供了供我们在外部添加新的 qch帮助文档的功能接口,一般有两中添…

八大技术趋势案例(虚拟现实增强现实)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…

Composer常见错误解决

Composer 是 PHP 社区广泛使用的一个依赖管理工具,它帮助开发者定义、管理和安装项目所需的库。在使用 Composer 的过程中,可能会遇到各种错误和问题。以下是一些常见的 Composer 错误及其解决方法: 1. 内存限制错误 错误信息:P…

QT QInputDialog弹出消息框用法

使用QInputDialog类的静态方法来弹出对话框获取用户输入,缺点是不能自定义按钮的文字,默认为OK和Cancel: int main(int argc, char *argv[]) {QApplication a(argc, argv);bool isOK;QString text QInputDialog::getText(NULL, "Input …

李宏毅【生成式AI导论 2024】第6讲 大型语言模型修炼_第一阶段_ 自我学习累积实力

背景知识:机器怎么学会做文字接龙 详见:https://blog.csdn.net/qq_26557761/article/details/136986922?spm=1001.2014.3001.5501 在语言模型的修炼中,我们需要训练资料来找出数十亿个未知参数,这个过程叫做训练或学习。找到参数后,我们可以使用函数来进行文字接龙,拿…

【数据分析面试】3.编写数据选取函数(Python)

题目 给定了一个名为 students_df 的学生数据表格 nameagefavorite_colorgradeTim Voss19red91Nicole Johnson20yellow95Elsa Williams21green82John James20blue75Catherine Jones23green93 编写一个名为 grades_colors 的函数,以选择仅当学生喜欢的颜色是绿色或…