Hessian序列化不设SerializerFactory性能问题
服务框架全面重构后,因换了通讯协议,采用Magic头识别新旧版本,
性能测试发现,在兼容旧版本模式下,性能下降10倍,
原来一个1ms到2ms的请求,现在需要11ms到12ms,
对比新旧版本代码,发现四个不同点:
(1) UnsafeByteArrayOutputStream是不是比ByteArrayOutputStream慢很多?
(2) 通过java.nio.ByteBuffer转换到mina的ByteBuffer映射写入慢很多?
(3) 重复使用一个ByteArrayOutputStream是不是比多个ByteArrayOutputStream慢很多?
(4) 没有设置SerializerFactory会比设置了慢很多?
逐个验证,前面三个对性能几乎没有影响,修改第四个,性能立马提升。
旧版本代码:
- private static final SerializerFactory _serializerFactory = new SerializerFactory();
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- Hessian2Output h2out = new Hessian2Output(bout);
- h2out.setSerializerFactory(_serializerFactory);
- h2out.writeObject(msg);
- h2out.flush();
- byte[] content = bout.toByteArray();
新版本代码:
- UnsafeByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(1024);
- Hessian2Output h2o = new Hessian2Output(bos);
- h2o.writeObject(connReq);
- h2o.flush();
- byte[] content = bos.toByteArray();
新代码没有调用h2o.setSerializerFactory(serializerFactory); 就因为这一句,性能下降10倍。 我们来看一下Hessian3.2.1的源代码:
- public void writeObject(Object object)
- throws IOException
- {
- if (object == null) {
- writeNull();
- return;
- }
-
- Serializer serializer;
-
- serializer = findSerializerFactory().getSerializer(object.getClass());
-
- serializer.writeObject(object, this);
- }
-
- public final SerializerFactory findSerializerFactory()
- {
- SerializerFactory factory = _serializerFactory;
-
- if (factory == null)
- _serializerFactory = factory = new SerializerFactory();
-
- return factory;
- }
看代码,在writeObject()时,如果发现没有设置SerializerFactory,会自动设一个SerializerFactory, 看起来好像没有问题,我们自己设的SerializerFactory也是直接new出来的,没做什么手脚, 那为什么性能会下降这么快呢?开始还真被这行代码唬住了,看起来没啥区别, 仔细一想,才发现,Hessian2Output对象是prototype的, 每次请求,都会创建一个实例,用完即销毁,这样的话,基于下面的方式:
- if (factory == null)
- _serializerFactory = factory = new SerializerFactory();
每一个Hessian2Output内部都会重新new SerializerFactory(); 应改为:
- private static final SerializerFactory DEFAULT_SERIALIZER_FACTORY =new SerializerFactory();
- if (factory == null)
- _serializerFactory = factory = DEFAULT_SERIALIZER_FACTORY;
从这里可以看出是创建SerializerFactory的开销非常大,导致性能下降严重, 这个应该算是Hessian的BUG,这种线程安全的工厂类,就不应该在设默认值时,每次都new一个。 大家用Hessian的时候请小心这个问题。 后续还发现,不设置SerializerFactory,会出现大量线程被阻塞:
分享到:
相关推荐
NULL 博文链接:https://qinghua0208.iteye.com/blog/493516
hessian序列化.pdf
介绍自己不会查吗?这里有一个点就是Hessian的序列化与反序列化与原生序列化与反序列化不同,就以使用的Resin链而言,其中的javax.naming.spi
NULL 博文链接:https://inter12.iteye.com/blog/1555678
主要通过对二者简单的实现方式的对比,介绍了Java序列化和hessian序列化的差异,具有一定参考价值,需要的朋友可以了解下。
NULL 博文链接:https://san-yun.iteye.com/blog/1688510
Hessian 2.0序列化协议规范
Nacos JRaft Hessian 反序列化 RCE 分析.pdf
hessian轻量级 rpc实现
java hessian-3.0.38.jar。修改了原生的jar包,解决了hessian 序列化BigDecimal的精度问题。注意,请在hessian服务端和客户端中分别替换此jar包哦!! 只替换服务端hessian jar包还是会有问题。
SOFA-Hessian 基于原生Hessian v4.0.51进行改进,目前已经蚂蚁金服内部稳定运行多年。我们修复了一些bug,增强了一些功能,并且添加了一些特性。包括:增加泛化序列化。增加 ClassNameResolver 和 ClassNameFilter ...
用LR对hessian接口做性能测试,使用JAVA协议,没有界面的性能测试
hessian.jar,Hessian的序列化输出 ,
默认就是⾛ dubbo 协议,单⼀⻓连接,进⾏的是 NIO 异步通信,基于 hessian 作为序列化协议。使⽤的场景是:传输数据量⼩ (每次请求在 100kb 以内),但是并发量很⾼。 为了要⽀持⾼并发场景,⼀般是服务提供者就⼏...
蚂蚁金服对 Hessian 序列化的定制版本 sofa-hessian-node 对应的 Java Hessian 版本是 v3.1.3。它对 模块做了进一步封装,通过预编译来提高性能。 安装 $ npm install sofa-hessian-node --save 示例 'use strict'; ...
a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...
远程调用方法就是HttpInvoker:他也是将参数和返回值通过Java的序列化机制进行编组和反编组,它具有RMI的支持所有可序列化对象的优点。试使用Http协议传输二进制流的,同时又具有Hessian、Burlap(传输xml文本)的...
我们介绍了Hessian正则化,并提出了一种称为Hessian正则化(AHNP)的新方法A-最优非负投影。 因此,AHNP不仅导致基于零件的精确表示,而且保留了所获得子空间的固有几何结构。 我们通过对真实世界应用程序的一组...
该案例有hessian java python,该案例有hessian java python,该案例有hessian java python