一次夜间接口超时的解决过程

某应用在类目客户端切换数据包时出现接口超时,经过排查,发现并非由堆空间不足或Sentinel限流引起,而是由于加载大文件触发Major Page Fault,导致进程挂起。解决方案是升级类目客户端并优化加载策略,以减少对服务的影响。
摘要由CSDN通过智能技术生成

背景

闲鱼某关键应用A依赖类目系统富客户端(下文简称类目客户端),旨在为闲鱼商品域其他应用提供各类商品类目及属性数据(下文简称CPV数据)查询服务。

每天凌晨,该应用所依赖的类目富客户端执行新老版本数据包切换时,应用提供的服务抖动非常明显,表现为大量接口超时(耗时100ms -> 3-5s),服务成功率明显下降(100% -> ~92%),RPC线程池活跃线程数上涨(50 -> ~100),抖动最长可持续20s,影响到商品发布、商品详情页等依赖CPV数据的关键业务场景;且夜间发生抖动,时间点不固定,抖动发生时开发同学也难以关注到,影响面较为不可控,因此需要排查并彻底解决此问题。

排查过程

其实这是一个表象很简单,但是根因藏得比较深的问题,笔者在排查过程中也走了一些弯路,也一并写出来供读者作为前车之鉴的参考。

堆空间不够?

结构化应用线上原先使用的是4C8G的标准规格容器,分配4G内存作为堆内存,截取部分JVM启动参数如下:

-Xms4g -Xmx4g -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=65 -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=55 -XX:G1HeapRegionSize=16m -XX:G1NewSizePercent=25 -XX:MaxGCPauseMillis=120 -XX:+ParallelRefProcEnabled   -XX:MaxDirectMemorySize=1g -XX:+TraceG1HObjAllocation -XX:ReservedCodeCacheSize=512m -XX:+UseCodeCacheFlushing

据反馈接口抖动的同学描述,在接口抖动的时间点,请求失败的机器发生了FGC。

undefined

由于本人先前在排查类似的FGC问题时,经常能在Heap Dump的支配树中看到类目客户端相关对象长期占据高位,是内存占用大户。所以难免主观印象先入为主,初步以为是切换版本的过程中,在老版本数据包卸载之前,可能会存在短暂的堆内空间占用double的情况。

而启动参数配置Eden区下限为25%。可能存在 老年代常驻占用 + 新数据包 > 4G 的情况引发FGC。

因此觉得 既然空间占用double不可避免,老年代常驻的堆空间短时间内又不可能显著下降,Eden区为了解决之前该应用发生Mixed GC时Eden区反常缩小导致YGC异常,又必须固定一个下限值,那只能是把容器内存规格扩大看看能否缓解 。

于是将应用容器基线升级到4C16G,设置在16G容器环境下,分配10G内存给堆空间,并逐步升级线上服务的容器规格。

结果花了两天时间,升级了线上大部分的容器后,查看监控,发现大规格的容器确实没有FGC了,且得益于超大的堆内存(10G),从GC监控上看甚至看不出有切包的动作。但是,RPC成功率还是会下跌(100% -> 97%),且RPC线程池线程数还是有少量上涨(50 -> ~71)。

由此可见,FGC并不是切包抖动的核心成因,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值