交易系统JVM内存优化

news/2024/12/22 16:33:06/

背景

新交易系统上线以后,业务指标(成单率)和系统指标(CPU、QPS、JVM内存)是我们重点关注的指标。

CPU较高:可以通过Arthas等工具查看繁忙线程的堆栈信息,定位具体的代码,具体分析。

QPS较高:首先评估一下,流量是否正常,正常的流量可以适当扩容,异常的流量适当调整限流的阈值。

本篇我们主要针对JVM内存进行分析和处理。

交易系统配置:JDK8、4C8G、垃圾回收器(PreNew + CMS)

关注点

  1. 元空间
  2. 老年代
  3. 年轻代
    在这里插入图片描述

元空间

系统上线一段时间之后,查看监控,元空间的内存比率已经逼近告警阈值(70%)。

对线上某一台机器的元空间内存快照数据进行逐一分析,发现元空间里面存在大量无用的类模版信息。

排查后发现,这些无用类的信息主要由两部分组成:

  1. 项目初建时,引入了大量的无用二方包。
  2. 项目初建时,引入了大量的无用工具类。

经过一个星期的梳理,将这些无用类一一剔除掉,因为代码改动量比较大,所以在预发环境观察了一个星期,经过QA团队进行了全case覆盖测试,如期上线。

上线后,效果显著,元空间内存比率从68%降低至50%。

但是随着上线之后,发现元空间的内存有呈线性趋势增长的形势。

于是,又仔细分析了元空间的快照数据,分析发现有很多Guava Aviator相关的类,于是又深挖了一遍这个组件的源码。

Guava Aviator在系统中,主要是做为规则引擎,具体用来做系统商级别的产品限购校验。

Guava Aviator底层用了ASM技术,每次执行该组件编译API接口的时候,都会动态创建一个类,这也就解释了为什么随着系统上线之后,Guava Aviator相关的类越来越多。

那有没有什么解决办法呢?有,Guava Aviator内部做了缓存机制,可以通过配置,使用该组件的缓存功能,这样就避免了每次都重新编译对象,创建新类。

老年代

经过分析老年代内存的快照数据,发现有两大对象:产品信息和合约信息。

产品信息:交易系统每次收单需要记录产品相关的信息。
合约信息:交易系统定位为B端交易系统,所以会和分销商和系统商进行合同签约。

产品中心和合约中心给域内提供的接口,返回的都是全量数据,数据量不仅庞大,而且接口性能还比较差,最高rt可达800ms。

这一部分数据超过1m,会直接存进老年代。

我这里的处理方案是针对产品查询接口增加客户端缓存,同时推动产品中心增加服务端缓存,当然这里还需要考虑缓存的时效性,因为在节假日的时候,产品的生命周期比较短,价库变动可能比较频繁,一不小心可能会造成资损,所以如果做客户端缓存,可以让产品中心在产品发生变动的时候,发送一个产品数据变更事件,交易系统监听该事件,进而失效缓存。

关于合约数据,变动不会特别频繁,缓存一天即可,可以让合约中心在合约发生变更的时候,发送一个合约数据变更事件,交易系统监听该事件,进而失效缓存。

当然,也可以针对垃圾回收器做一些设置,比如调高数据进入老年代的阈值(1m配置成2m),调大年轻代比例等。

在分析老年代的快照数据时,又发现了Guava aviator相关的数据信息。我们开启Guava aviator的缓存功能的时候,组件内存用ThreadLocal缓存了编译之后的对象,但是没有显示remove,因为项目中用的都是线程池,针对ThreadLocal内部的Entry对象是强引用,导致内存泄漏。

这里有两个方案:

  1. 根据Aviator官方所述,升级版本即可,高版本fix了这个bug。
  2. 编译对象缓存在本地,可使用LRU算法,做容量控制。

年轻代

针对年轻代,有些时候会发生一些频繁的Young GC,但是抓了快照信息,并没有发现什么问题。

这里可以调整年轻代的内存比率。

当时也想升级垃圾回收器为G1,因为G1的数据结构都是一个一个Region,内部有优先级队列可以控制GC响应时间,而且还是整堆回收,性能相对来说要优于PreNew+CMS这一套垃圾回收器。这里主要考虑的是交易系统的稳定性,升级垃圾回收器算是比较大的改动,而且目前使用CMS并没有太大问题,就放弃了这个方案。

最后,采取的方案就是将4C8G的配置,升级为了4C12G的配置,效果显著。


http://www.ppmy.cn/news/1510650.html

相关文章

Linux环境开发工具【yum与vim】

🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 文章目录 1.Linux软件包管理器yum1.1 快速使用yum 2. Linux编辑器-vim的使用2.1 vim的基本…

3.类和对象(中)

1. 类的默认成员函数 默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数(就是我们不写,编译器会默认生成一份)。一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数&#xff0…

给既有exe程序添加一机一码验证

原文地址:李浩的博客 lihaohello.top 本科期间开发过一款混凝土基本构件设计程序,该程序是一个独立的exe可执行文件,采用VC静态链接MFC库编制而成。近期,需要为该程序添加用户注册验证的功能,从而避免任何用户获取该程…

谈对象系列:C++类和对象

文章目录 一、类的定义1.1类定义的格式类的两种定义方法结构体: 1.2访问限定符1.3类域 二、实例化2.1变量的声明和定义2.2类的大小计算空类的大小(面试): 三、this指针小考题 一、类的定义 1.1类定义的格式 使用class关键字&…

【stm32项目】多功能智能家居室内灯光控制系统设计与实现(完整工程资料源码)

多功能智能家居室内灯光控制系统设计与实现 目录: 目录: 前言: 一、项目背景与目标 二、国内外研究现状: 2.1 国内研究现状: 2.2 国外研究现状: 2.3 发展趋势 三、硬件电路设计 3.1 总体概述 3.2 硬件连接总…

大公报发表欧科云链署名文章:发行港元稳定币,建Web3.0新生态

欧科云链研究院资深研究员蒋照生近日与香港科技大学副校长兼香港Web3.0协会首席科学顾问汪扬、零壹智库创始人兼CEO柏亮,在大公报发布联合署名文章 ——《Web3.0洞察 / 发行港元稳定币,建Web3.0新生态》,引发市场广泛讨论。 文章就香港稳定币…

视频美颜SDK与直播美颜工具:实现实时美颜的关键技术详解

本文将详细解析视频美颜SDK与直播美颜工具的核心技术,探讨其如何实现实时美颜效果。 一、视频美颜SDK的核心技术 1.人脸识别与面部特征提取 通过这些特征点,SDK可以对面部进行精确定位,为后续的美颜处理提供基础。 2.实时图像处理 这包括…

可乐机的设计验证

前言 状态机(State Machine)是一种数学模型,用于表示具有有限状态集合的系统。它通过定义状态、转移规则和事件,描述系统在不同条件下的行为。状态机的核心概念包括状态、事件、转移和动作。状态是系统的具体条件或配置&#xff0…