Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Hession反序列化导致CPU占用飙高

Hession反序列化导致CPU占用飙高

作者头像
高爽
发布于 2017-12-28 08:56:07
发布于 2017-12-28 08:56:07
2.3K00
代码可运行
举报
文章被收录于专栏:高爽的专栏高爽的专栏
运行总次数:0
代码可运行

背景

今天发布一个线上服务,暂且称之为O,发布完后,依赖O服务的2个服务C和W大量Time报警,并且这两个服务的CPU占用都飙到了40%左右,平时只有10%的样子。

这时去看O服务的监控,Time并没有升高,QPS反倒降了一半。同时C和W服务器日志中出现了大量的WARNING,信息如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.ClassNotFoundException: com.我是不可描述的信息.PropertyAo
Dec 02, 2016 6:24:33 PM com.alibaba.com.caucho.hessian.io.SerializerFactory getDeserializer
WARNING: Hessian/Burlap: 'com.我是不可描述的信息.PropertyAo' is an unknown class in WebappClassLoader
  context:
  delegate: false
  repositories:
    /WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@21bf4c80

短时间内找不到原因,且C服务是核心服务,找QA童鞋把O服务回滚,C和W报警恢复,CPU占用回到正常。

定位

可能见过这个WARNING的朋友已经知道了我这次发布干了啥,其实就是在API返回的模型中增加了两个自定义类型的属性,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private List<PropertyAo> properties1;
private List<PropertyAo> properties2;

这两个属性W中会用到,之所以会有上面提到的WARNING,是由于我先发布了O服务,O服务中设置了这两个属性,而W服务还没有发布,这样Hession在反序列化的时候,检测到了PropertyAo不存在,所以给出了WARNING。但这与CPU飙高有关系吗? 与同事讨论了一番,他提到了Hession反序列化时会使用到反射,他之前遇到过CPU占用飙高的情况(是由于反射代码被大量调用),这点提醒了我,顺着com.alibaba.com.caucho.hessian.io.SerializerFactory getDeserializer这个方法看到了这样的实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {
    Class cl = Class.forName(type, false, _loader);
    deserializer = getDeserializer(cl);
} catch (Exception e) {
    log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + _loader + ":\n" + e);
    log.log(Level.FINER, e.toString(), e);
}

可以看到Hession是通过名字去拿到Class,这里使用了反射,当反射失败时就会打出上面的warning。这时聪明的你可能想到了,即使没有失败也是在使用反射啊,继续向下看代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (deserializer != null) {
    if (_cachedTypeDeserializerMap == null)
        _cachedTypeDeserializerMap = new HashMap(8);

    synchronized (_cachedTypeDeserializerMap) {
        _cachedTypeDeserializerMap.put(type, deserializer);
    }
}

反射成功就会将其cache起来,也就是说,如果反射成功,只会调用一次反射,反射失败,则每次都会执行反射。

验证

先将C升级到最新api,然后发布,再发布O服务,C表现正常,W的CPU又开始飙高,执行jstack看一下事故现场,可以看到一些线程正在执行反射,栈信息如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"New I/O worker #17" daemon prio=10 tid=0x00007fb1ed33b000 nid=0x63fe runnable [0x00007fb22fcfa000]
    java.lang.Thread.State: RUNNABLE
         at java.lang.Class.forName0(Native Method)
         at java.lang.Class.forName(Class.java:270)
         at com.alibaba.com.caucho.hessian.io.SerializerFactory.getDeserializer(SerializerFactory.java:500)

解决

  • 当服务端模型升级时,尤其是新增自定义类型时,尽量让所有消费端升级,但当消费端过多时,这个方案成本太高,且不友好
  • 改进SerializerFactory,把反射失败的情况也缓存,避免重复反射,已推动公司内部解决
  • 给Dubbo提了issue,不过估计不会解决

结论

Hession默认的反序列化实现满足下面2点条件时,就会导致CPU占用飙高:

  • 服务端新增了自定义类型
  • 对该服务接口的调用QPS较高,我的应用中是100+

其本质原因还是由于反射,所以开发过程中慎用反射,反射得到的信息尽量Cache,避免频繁反射。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-12-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一次 Dubbo 线程上下文类加载器的疑难杂症分析
有业务(Java)的同学反馈,在接入了 devops 的某些 javaagent 以后会极大概率出现 dubbo 调用失败,dubbo 接口中用到的业务类都提示找不到,导致反序列化失败,部分日志输出如下:
挖坑的张师傅
2023/03/03
9800
一次 Dubbo 线程上下文类加载器的疑难杂症分析
Tomcat 应用中并行流带来的类加载问题
随着 Java8 的不断流行,越来越多的开发人员使用并行流(parallel)这一特性提升代码执行效率。但是,作者发现在 Tomcat 容器中使用并行流会出现动态加载类失败的情况,通过对比 Tomcat 多个版本的源码,结合并行流和 JVM 类加载机制的原理,成功定位到问题来源。本文对这个问题展开分析,并给出解决方案。
2020labs小助手
2019/09/23
1.5K0
[New I/O server worker #1-2] Hessian/Burlap:is an unknown class in org.springframework.boot.loader.L
https://github.com/apache/dubbo/issues/819
翎野君
2024/11/21
1060
Apache Dubbo Hessian2 异常处理时反序列化(CVE-2021-43297)
上周看到Apache官方又发布了一个Apache Dubbo Hessian2的漏洞(https://lists.apache.org/thread/1mszxrvp90y01xob56yp002939c7hlww),来看看这个描述:
Seebug漏洞平台
2022/02/23
1.2K0
Apache Dubbo Hessian2 异常处理时反序列化(CVE-2021-43297)
Java安全之Hessian反序列化
Hessian是一个基于HTTP协议采用二进制格式传输的RPC服务框架,相对传统的SOAP web service,更轻捷。Hessian是Apache Dubbo在Java语言的实现,该框架还提供了Golang、Rust、Node.js 等多语言实现。Hessian 是一种动态类型、二进制序列化和 Web 服务协议,专为面向对象的传输而设计。
ph0ebus
2023/08/26
1.1K0
Hessian 原理分析
网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协议,网络 IO ,主要有 bio 、 nio 、 aio 三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
Java架构师历程
2019/03/08
1.2K0
Hessian 反序列化及相关利用链
前不久有一个关于Apache Dubbo Http反序列化的漏洞,本来是一个正常功能(通过正常调用抓包即可验证确实是正常功能而不是非预期的Post),通过Post传输序列化数据进行远程调用,但是如果Post传递恶意的序列化数据就能进行恶意利用。Apache Dubbo还支持很多协议,例如Dubbo(Dubbo Hessian2)、Hessian(包括Hessian与Hessian2,这里的Hessian2与Dubbo Hessian2不是同一个)、Rmi、Http等。Apache Dubbo是远程调用框架,既然Http方式的远程调用传输了序列化的数据,那么其他协议也可能存在类似问题,例如Rmi、Hessian等。@pyn3rd师傅之前在twiter[1]发了关于Apache Dubbo Hessian协议的反序列化利用,Apache Dubbo Hessian反序列化问题之前也被提到过,这篇文章[2]里面讲到了Apache Dubbo Hessian存在反序列化被利用的问题,类似的还有Apache Dubbo Rmi反序列化问题。之前也没比较完整的去分析过一个反序列化组件处理流程,刚好趁这个机会看看Hessian序列化、反序列化过程,以及marshalsec[3]工具中对于Hessian的几条利用链。
Seebug漏洞平台
2020/03/10
1.6K0
Hessian 反序列化及相关利用链
Java安全--反序列化之Jython链(2)
本文属于OneTS安全团队成员v4por的原创文章,转载请声明出处!本文章仅用于学习交流使用,因利用此文信息而造成的任何直接或间接的后果及损失,均由使用者本人负责,OneTS安全团队及文章作者不为此承担任何责任。
OneTS安全团队
2025/02/07
880
Java安全--反序列化之Jython链(2)
SOFA-Hessian反序列漏洞
笔者注意到https://github.com/alipay/sofa-hessian 提到了安全相关:
安全乐观主义
2019/11/20
1.1K0
Web漏洞 | JAVA反序列化漏洞
1、由于很多站点或者RMI仓库等接口处存在java的反序列化功能,于是攻击者可以通过构造特定的恶意对象序列化后的流,让目标反序列化,从而达到自己的恶意预期行为,包括命令执行,甚至 getshell 等等。
谢公子
2022/01/13
8300
Web漏洞 | JAVA反序列化漏洞
JSON 反序列化 Long 变 Integer 或 Double 问题
工作中可能会遇到对 Map 进行 JSON 序列化,其中值中包含 Long 类型的数据,反序列化后强转 Long 时报类型转换异常的问题。
明明如月学长
2021/10/18
3.6K0
Spring中使用BeanUtils.copyProperties()导致Hessian/Burlap:ClassNotFoundException
[New I/O worker #4] WARN c.a.c.c.hessian.io.SerializerFactory - Hessian/Burlap: 'XX.XX.XBean' is an unknown class in java.net.URLClassLoader@988246e:
翎野君
2024/11/21
1190
IDEA动态调试(二)——反序列化漏洞(Fastjson)
成因:在把其他格式的数据反序列化成java类的过程中,由于输入可控,导致可以执行其他恶意命令,但追根究底是需要被反序列化的类中重写了readObject方法,且被重写的readObject方法/调用链中被插入了恶意命令。
Jayway
2020/03/16
3.3K0
IDEA动态调试(二)——反序列化漏洞(Fastjson)
Java 反序列化学习
讲的比较清楚的文章:https://www.cnblogs.com/ityouknow/p/5603287.html
wywwzjj
2023/05/09
1.5K0
Java 反序列化学习
CommonsCollections2 反序列化链分析
getDecalaredField是java.lang.Class中的一个方法,该方法返回一个Field对象,它反映此Class对象所表示的类或接口的指定已声明字段。 name参数是一个字符串,指定所需字段的简单名称。
yulate
2023/05/02
3840
CommonsCollections2 反序列化链分析
Java安全之RMI反序列化
RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC的诞生起源于分布式的使用,最开始的系统都是在一台服务器上,这样本地调用本无问题。但随着网络爆炸式的增长,单台服务器已然不满足需求,出现了分布式,接口和实现类分别放到了两个服务器上,怎么调用呢?JVM不同,内存地址不同,不可能直接访问调用。由于 RPC 的使用还是过于麻烦,Java RMI 便由此产生。
ph0ebus
2023/05/24
3140
Java安全之RMI反序列化
Fastjson < 1.2.68版本反序列化漏洞分析篇
点击上方蓝色“程序猿DD”,选择“设为星标” 回复“资源”获取独家整理的学习资料! 作者 | ale_wong@云影实验室 来源 | https://www.anquanke.com/post/id/219731 前言 迟到的Fastjson反序列化漏洞分析,按照国际惯例这次依旧没有放poc。道理还是那个道理,但利用方式多种多样。除了之前放出来用于文件读写的利用方式以外其实还可以用于SSRF。 一、漏洞概述 在之前其他大佬文章中,我们可以看到的利用方式为通过清空指定文件向指定文件写入指定内容(用到第三方
程序猿DD
2023/04/04
1.4K0
Fastjson < 1.2.68版本反序列化漏洞分析篇
Dubbo使用jsr303框架hibernate-validator遇到 ConstraintDescriptorImpl could not be instantiated
Dubbo可以集成jsr303标准规范的验证框架,作为验证框架不二人选的hibernate-validator是大家都会经常在项目中使用的,但是在Dubbo使用是会发生下面这个问题。
王念博客
2019/07/25
1.7K0
dubbo序列化问题(三)子类覆盖父类字段hession反序列化获取不到
在进行dubbo开发中遇到一个问题,当是用hession2进行序列化时,子类和父类有相同的字段时,hession2反序列化获取不到该字段数据,如下:
一笠风雨任生平
2019/08/02
1.2K0
Java安全-反序列化-5-CC3
正常情况下,Java会根据配置项sun.boot.class.path和java.class.path中列举到的基础路径(这些路径是经过处理后的java.net.URL类)来寻找.class文件来加载,而这个基础路径有三种情况:
Naraku
2022/04/26
4470
Java安全-反序列化-5-CC3
推荐阅读
相关推荐
一次 Dubbo 线程上下文类加载器的疑难杂症分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验