如何从消失的异常堆栈定位线上问题 | 京东云技术团队
一、消失的异常堆栈
在618保障大促稳定性过程中,消失的异常堆栈可能会给我们带来严重的麻烦,因为这些堆栈信息是我们解决线上问题的关键之一。如何快速定位问题?想必大家心中都有自己的答案,当然最简单直接的办法还是查找异常堆栈信息。
然而有时异常堆栈并不完整,只有一句描述,如下:
Caused by: java.lang.NullPointerException
造成这种现象的原因其实很简单,原因如下:
JIT编译器对异常进行了优化,当代码中的某个位置抛出同一个异常很多次后, JIT服务端编译器(C2)会将其优化成抛出一个事先编译好的、类型匹配的异常,异常堆栈信息就看不到了。
二、Fast Throw
Fast Throw,字段上理解就是快速抛异常,目前需要满足以下条件才有如此的优化:
-
只针对HotSpot VM才有, 例如oracleJDK, libericaJDK等
-
特定位置抛出很多次,其实就是JIT将它优化了
-
JIT必须使用C2才会这样优化,不抛出原来的异常,改用fast throw抛出
-
这是一个事先分配好的异常,message和堆栈都是空的
可以看出,如果某个异常在同一位置被抛出多次,会被JIT C2优化成空异常,例如本文的NullPointerException,既没有message,也没有堆栈.但他的速度非常快,不用分配内存和获取堆栈.
如果想关闭这个优化,设置-XX:-OmitStackTraceInFastThrow即可。
存在即合理,既然存在fast throw的优化,必然有其价值。fast throw优化的原因是为了提高性能。当同一种异常在相同的位置被抛出多次,编译器就会重新编译此方法。重编译后,编译器可能会使用不提供跟踪的预分配异常来选择更快的策略。
本地测试了一下抛出NullPointerException,在开启与关闭fast throw的性能。
执行次数 | 开启Fast Throw | 关闭Fast Throw |
---|---|---|
10w | 996ms | 3525ms |
100w | 5983ms | 28345ms |
500w | 35678ms | —— |
言而简之,不能因此出现了消失的异常堆栈就尝试关闭fast throw优化功能。
三、问题原因定位
对于线上环境中触发了Fast Throw机制,则可以通过向前追溯相同的日志来定位问题。
如在开门红中,有个接口的可用率调到98.3%(不是100%),如下图。
然后搜索日志发现大量的Caused by: java.lang.NullPointerException,没有详细的异常堆栈,很显然是由于fast throw导致的,然后不断向前追溯相同的日志来定位问题如下图。
19:05:32.592 [JSF-BZ-22001-245-T-522] ERROR com.jd.m.soa.shop.service.jsf.shop.impl.ShopSoaOutSideJsfServiceImpl - ShopSoaOutSideJsfServiceImpl.getKACard error com.jd.sirector.SirectorException: java.lang.NullPointerException at com.jd.sirector.ScriptRuntime.waitIfNecessary(ScriptRuntime.java:129) ~[sirector-core-0.2.2-beta.jar:?] at com.jd.sirector.ScriptRuntime.run(ScriptRuntime.java:66) ~[sirector-core-0.2.2-beta.jar:?] at com.jd.sirector.Sirector.publish(Sirector.java:153) ~[sirector-core-0.2.2-beta.jar:?] **************** at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_60] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_60] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_60] at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_60] Caused by: java.lang.NullPointerException at com.jd.******************wProxy.java:321) ~[shop-soa-service-1.1.jar:?] ************** ... 5 more 19:05:44.063 [JSF-BZ-22001-245-T-503] ERROR com.jd.m.soa.shop.service.jsf.shop.impl.ShopSoaOutSideJsfServiceImpl - ShopSoaOutSideJsfServiceImpl.getKACard error com.jd.sirector.SirectorException: java.lang.NullPointerException at com.jd.sirector.ScriptRuntime.waitIfNecessary(ScriptRuntime.java:129) ~[sirector-core-0.2.2-beta.jar:?] at com.jd.sirector.ScriptRuntime.run(ScriptRuntime.java:66) ~[sirector-core-0.2.2-beta.jar:?] at com.jd.sirector.Sirector.publish(Sirector.java:153) ~[sirector-core-0.2.2-beta.jar:?] **************** at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_60] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_60] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_60] at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_60] Caused by: java.lang.NullPointerException 19:05:47.831 [pool-84-thread-10] ERROR com.jd.m.soa.shop.service.base.shop.impl.ShopBaseServiceImpl - 上游返回的店铺星级值非法。value=0.0
出现问题的原因找到了,接着就分析原因。原因很简单,由于某一台机器性能波动导致接口超时将兜底对象缓存,后续逻辑在处理的过种中对象中的Boolean属性值在转boolean时出现NPE,问题根源还是代码兼容性不足够好。
这这台机器进行系统视图层分析,发现TCP重传数较高,如下左图。
四、问题原因分析
TCP重传主要是为了保证数据传输的可靠性,TCP是一种保证可靠传输的机制,如重传与确认机制、数据校验、数据分片、流量控制、拥塞控制等。TCP重传的类型有超时重传和快速重传。超时重传是在请求包发送出去时开启计时器,当到达时间之后,没有收到ACK,则进行重传直到达到上限次数或者收到ACK。快速重传则依赖于数据包的期望序列号,并进行一致性检查。
- 多台机器或者同一机房同时TCP重传
很大原因是网络抖动
- 单机或者某个应用出现TCP重传
一般是由于链路的服务器或端口无法访问,对于虚拟机或者docker,还需要考虑宿主机的问题。
通过系统级分析,最后确定是由于宿主机连接性问题导致docker实例TCP重传增高,当然最重要的是补充相关的指标监控。
总之,无论是在大促期间还在平时,遇到问题首先解决好问题,更为重要的是追本溯原,找出问题的根因,以便推动团队优化和提升。
作者:京东零售 张帅
来源:京东云开发者社区

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
当金融风控遇上人工智能,众安金融的实时特征平台实践
导读:随着企业数字化转型升级,线上业务呈现多场景、多渠道、多元化的特征。数据要素价值的挖掘可谓分秒必争,业务也对数据的时效性和灵活性提出了更高的要求。在庞大分散、高并发的数据来源背景下,数据的实时处理能力成为企业提升竞争力的一大因素。今天分享的是众安金融实时特征平台实践。 下面的介绍分为四个部分: 众安金融 MLOps 简介 实时特征平台架构设计 实时业务特征计算详解 反欺诈场景的特征应用 分享嘉宾|郭育波 众安 高级技术专家 众安金融 MLOps 简介 什么是 MLOps (1)定义 MLOps 是将机器学习、数据工程和 DevOps 融合在一起,从而实现机器学习模型的高效迭代和持续稳定地应用于生产业务的一套方法架构。所以它是一套实践方法论,是一套架构方案。 (2)协作团队 ① 数据产品团队:定义业务目标,衡量业务价值。 ② 数据工程团队:采集业务数据,然后对数据进行清洗转换。 ③ 数据科学家团队:构建 ML 解决方案,开发相应的特征模型。 ④ 数据应用团队:模型应用,对特征进行持续的监控。 众安金融 MLOps 流程说明 (1)样本准备,产品业务团队定义业务范围,确定建模的目标,选...
- 下一篇
typescript的必要性及使用 | 京东云技术团队
1 前言 作为一个前端语言,Javascript从最初只是用来写页面,到如今的移动终端、后端服务、神经网络等等,它变得几乎无处不在。如此广阔的应用领域,对语言的安全性、健壮性以及可维护性都有了更高的要求。尽管ECMAScript标准在近几年有了长足的进步,但是在类型检查方面依然毫无建树。在这种情况下TypeScript应运而生。 2 为什么要使用TypeScript 在JavaScript的开发过程中,相信经常会遇到以下这种场景: 场景一: 你需要调用一个别人开发的函数 function funcName(paramA,paramB,paramC,paramD){…},但是很不幸,这个家伙没有留下任何注释,为了弄清楚参数的类型,你不得不硬着头皮去读里面的逻辑; 场景二: 为了保证代码的健壮性,你很负责任的对函数的每个输入参数进行了各种假设,导致函数内一多半代码都是对参数(类型、个数等)的判断逻辑; 场景三: 老板很看好你,让你维护一个重要的底层类库,你殚精竭虑优化了一个参数类型,在提交代码前,不知道有多少地方调用,你是否感到脊背发凉? 等等… 以上情况归结底,是因为 JavaScrip...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路