- 浏览: 1680309 次
- 性别:
- 来自: 杭州699号
文章分类
最新评论
-
莫莫摸:
为什么不用dubbo
RCP数据传输模型回顾 -
大胡子爸爸:
String, Class 都实现了Serializable接 ...
RPC框架几行代码就够了 -
lss598018587:
谢谢大神分享,比起新手看复杂的dubbo框架还不如看大神的这一 ...
RPC框架几行代码就够了 -
15606915740:
你好,请问一下。<dubbo:consumer filt ...
Dubbo文档 -
joqk12345:
...
一些设计上的基本常识
转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/experience_1089/hessian-set-serializerfactory-performance.html
服务框架全面重构后,因换了通讯协议,采用Magic头识别新旧版本,
性能测试发现,在兼容旧版本模式下,性能下降10倍,
原来一个1ms到2ms的请求,现在需要11ms到12ms,
对比新旧版本代码,发现四个不同点:
(1) UnsafeByteArrayOutputStream是不是比ByteArrayOutputStream慢很多?
(2) 通过java.nio.ByteBuffer转换到mina的ByteBuffer映射写入慢很多?
(3) 重复使用一个ByteArrayOutputStream是不是比多个ByteArrayOutputStream慢很多?
(4) 没有设置SerializerFactory会比设置了慢很多?
逐个验证,前面三个对性能几乎没有影响,修改第四个,性能立马提升。
旧版本代码:
新版本代码:
新代码没有调用h2o.setSerializerFactory(serializerFactory);
就因为这一句,性能下降10倍。
我们来看一下Hessian3.2.1的源代码:
看代码,在writeObject()时,如果发现没有设置SerializerFactory,会自动设一个SerializerFactory,
看起来好像没有问题,我们自己设的SerializerFactory也是直接new出来的,没做什么手脚,
那为什么性能会下降这么快呢?开始还真被这行代码唬住了,看起来没啥区别,
仔细一想,才发现,Hessian2Output对象是prototype的,
每次请求,都会创建一个实例,用完即销毁,这样的话,基于下面的方式:
每一个Hessian2Output内部都会重新new SerializerFactory();
应改为:
从这里可以看出是创建SerializerFactory的开销非常大,导致性能下降严重,
这个应该算是Hessian的BUG,这种线程安全的工厂类,就不应该在设默认值时,每次都new一个。
大家用Hessian的时候请小心这个问题。
后续还发现,不设置SerializerFactory,会出现大量线程被阻塞:
(下图为VisualVM截图,红色标识的片断为Blocked状态)
http://pt.alibaba-inc.com/wp/experience_1089/hessian-set-serializerfactory-performance.html
服务框架全面重构后,因换了通讯协议,采用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,会出现大量线程被阻塞:
(下图为VisualVM截图,红色标识的片断为Blocked状态)
评论
3 楼
chozee
2015-10-09
真正影响性能的是如下代码而不是new Factory,因为new的Factory需要重新缓存Serializer,请指教。
public Serializer getSerializer(Class cl) throws HessianProtocolException { Serializer serializer; serializer = (Serializer) _staticSerializerMap.get(cl); if (serializer != null) return serializer; if (_cachedSerializerMap != null) { synchronized (_cachedSerializerMap) { serializer = (Serializer) _cachedSerializerMap.get(cl); } if (serializer != null) return serializer; } for (int i = 0; serializer == null && _factories != null && i < _factories.size(); i++) { AbstractSerializerFactory factory; factory = (AbstractSerializerFactory) _factories.get(i); serializer = factory.getSerializer(cl); } if (serializer != null) { } else if (JavaSerializer.getWriteReplace(cl) != null) serializer = new JavaSerializer(cl, _loader); else if (HessianRemoteObject.class.isAssignableFrom(cl)) serializer = new RemoteSerializer(); // else if (BurlapRemoteObject.class.isAssignableFrom(cl)) // serializer = new RemoteSerializer(); else if (Map.class.isAssignableFrom(cl)) { if (_mapSerializer == null) _mapSerializer = new MapSerializer(); serializer = _mapSerializer; } else if (Collection.class.isAssignableFrom(cl)) { if (_collectionSerializer == null) { _collectionSerializer = new CollectionSerializer(); } serializer = _collectionSerializer; } else if (cl.isArray()) serializer = new ArraySerializer(); else if (Throwable.class.isAssignableFrom(cl)) serializer = new ThrowableSerializer(cl, getClassLoader()); else if (InputStream.class.isAssignableFrom(cl)) serializer = new InputStreamSerializer(); else if (Iterator.class.isAssignableFrom(cl)) serializer = IteratorSerializer.create(); else if (Enumeration.class.isAssignableFrom(cl)) serializer = EnumerationSerializer.create(); else if (Calendar.class.isAssignableFrom(cl)) serializer = CalendarSerializer.create(); else if (Locale.class.isAssignableFrom(cl)) serializer = LocaleSerializer.create(); else if (Enum.class.isAssignableFrom(cl)) serializer = new EnumSerializer(cl); if (serializer == null) serializer = getDefaultSerializer(cl); if (_cachedSerializerMap == null) _cachedSerializerMap = new HashMap(8); synchronized (_cachedSerializerMap) { _cachedSerializerMap.put(cl, serializer); } return serializer; }
2 楼
czltx224
2013-01-24
...能具体说明在哪个类里面吗?这样我找不到,另外你说的新版和旧版具体指的是哪个版本?
1 楼
may_cauc
2011-02-14
楼主看代码很细啊。
我发现hessian文档极度匮乏,社区也不行。我现在整合seam和hessian,来回协议不一致,已经开始读源代码好几天了,也没啥头绪。
我发现hessian文档极度匮乏,社区也不行。我现在整合seam和hessian,来回协议不一致,已经开始读源代码好几天了,也没啥头绪。
发表评论
-
能力成长模型
2012-05-09 00:28 22672最近看了温伯格1986年出版的《技术领导之路》, 很老的书,讲 ... -
以HTTL为例讲讲模块分包&领域模型&扩展框架
2011-10-09 20:08 16449注:该博客内容已加入 ... -
使用Map参数的Webx3扩展
2011-08-28 02:10 5852因Webx3是开源的,所以把这个简单的Webx3扩展发在博客上 ... -
Netty内存泄露
2011-08-02 20:09 24865转于自己在公司的Blog: ... -
Grizzly和Netty以及Mina简单性能对比
2011-07-17 02:48 29612转于自己在公司的Blog: http://pt.alibaba ... -
RPC框架几行代码就够了
2011-07-14 00:34 89497转于自己在公司的Blog: http://pt.alibaba ... -
魔鬼在细节中
2011-05-24 14:50 32255转于自己在公司的Blog: ... -
Dubbo扩展点重构
2011-05-12 22:09 38759转于自己在公司的Blog: http://pt.alibaba ... -
配置设计
2011-03-09 23:41 23432转于自己在公司的Blog: ... -
[转]HTML5设计原理
2011-03-09 22:57 7655Jeremy Keith在 Fronteers 2010 ... -
动态代理方案性能对比
2010-11-17 21:38 45640转于自己在公司的Blog: http://pt.alibaba ... -
防痴呆设计
2010-11-05 18:58 17510转于自己在公司的Blog: ... -
负载均衡扩展接口重构
2010-11-05 18:53 8628转于自己在公司的Blog: ... -
分布式服务框架常被质疑的价值
2010-11-05 18:52 5677转于自己在公司的Blog: http://pt.alibaba ... -
Hessian3.2.1在序列化32.5k字符串时的问题
2010-11-05 18:49 7115转于自己在公司的Blog: http://pt.alibaba ... -
一些设计上的基本常识
2010-07-05 19:28 27438转于自己在公司的Blog: ... -
谈谈扩充式扩展与增量式扩展
2010-06-12 19:46 18969转于自己在公司的Blog: http://pt.alibaba ... -
Scaling Architecture
2010-02-25 10:31 4052Scaling Second Life: http://p ... -
EBay SOA
2010-02-23 18:23 4736EBay SOA PPT -
服务化基础设施
2009-11-15 23:11 6216服务化,也可以叫SOA, ...
相关推荐
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