ejb与java序列化(3) 开启enable-call-by-reference

问题终于找到,简单的说是因为java 序列化的效率低下,而ejb调用之间又大量使用序列化,因此造成极大的性能消耗,而且也影响到响应时间。仔细分析了一下项目情况,呵呵,情况非常严重,系统架构是按照三层来设计的,每个层都是ejb,调下一层都是通过远程接口,而且层之间可能还多个ejb的调用。

(说句题外话,这种设计个人感觉非常,恩,不理解,性能杀手,而且ejb配置极其复杂,当然或者ejb本来就是如此,ebj和weblogic对我来说是很陌生很高深的东西,目前还没有深入掌握。)

很自然的会想到ejb2.0中的配置项enable-call-by-reference,如果能够开启就可以避免远程接口调用中的序列化。检查配置文件发现几乎能设置enable-call-by-reference的地方都设置为true了,奇

怪,再检查部署方式时发现,恩,晕倒,被部署到不同的ear包中了。

不同的ear包,enable-call-by-reference就算设置位true也开启不了吧?

接下来的改进方式,很自然就想到,如果能打包到同一个ear中,就可以在不改动代码,不改动部署文件的情况下解决这个问题,似乎是一个不错的好想法。

谨慎起见,同时为了拿到足够的证据来说法上层,先做个试验先。

模拟公司的项目结构,单独写了一个project,1个servlet负责接受外界请求,3个SLSB模拟三层工作,ejb直接只提供远程接口,然后打包到同一个ear包进行测试。当然enable-call-by-reference设置为true

和false来进行对比测试。

为了突出这个差异,ejb中都不进行任何操作,也不sleep。这样消耗就主要体现在java 序列化的消耗上,而且为了模拟真实情况,参数设置的比较大,里面放了1000个instance。

使用loadrunner,开启100个测试线程,通过http访问servlet,测试时间一分钟,看能执行多少次请求,测试结果如下:

enable-call-by-reference = false : 558

enable-call-by-reference = true : 21163

由于这个结果的差异性实在是太大了,因此没有必要进行多次测试,近40倍的差异完全可以反应问题了,当时实际项目中应该远没有这么夸张。

总结一下:

1. java serialize 非常慢

2. enable-call-by-reference可以有效避免这个开销

因此,能enable-call-by-reference就尽量enable-call-by-reference。

ps:顺便将这个测试的eclipse project也分享出来吧,请在这里下载

http://www.fs2you.com/files/045b367d-5d23-11dd-a2ed-0014221b798a/

时间: 2024-11-01 13:36:25

ejb与java序列化(3) 开启enable-call-by-reference的相关文章

ejb与java序列化(1) 发现并分析问题

这是加入新公司后接手的第一个项目,使用weblogic9.2 + ejb2.0,压力测试时发现速度非常慢,响应时间很不理想,检查日志发现,某些ejb相互调用时方法调用的时间非常长,高达300-500毫秒.非常夸张,因为两个日志之间只是间隔了一个ejb调用.通过thread dump分析后发现有相当多的线程在wait,检查线程调用绽发现是在将参数进行序列化时,线程试图加锁但是锁被占用,因此处于等待状态.考虑到thread dump的这一瞬间,有多达30-50个线程都在同时试图在同一个锁上加锁,很明

ejb与java序列化(2) 测试代码

接上篇,有兴趣的朋友可以直接拿我的测试代码自行测试,请自行修改诸如线程数,执行时间,序列化的数据量大小等参数.如果想尝试做thread dump,可以打开相关的两个注释,会更方便一些,代码中都有相应的注释可供参考. 测试代码如下: package test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Seri

Java序列化(Serialization) 机制_java

  Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端.这就需要有一种可以在两端传输数据的协议.Java序列化机制就是为了解决这个问题而产生. 将对象状态转换成字节流之后,可以用java.io包中各种字节流的类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机.对象序列化功能非常简单.强大,在RMI.Socket.JMS.EJB都有应用.对象序列化问题在网络编程中并不是最核心的课题,但却相当重要,具有许多实用意义. java对象序列

java序列化的控制

正如大家看到的那样,默认的序列化机制并不难操纵.然而,假若有特殊要求又该怎么办呢?我们可能有特殊的安全问题,不希望对象的某一部分序列化:或者某一个子对象完全不必序列化,因为对象恢复以后,那一部分需要重新创建. 此时,通过实现Externalizable接口,用它代替Serializable接口,便可控制序列化的具体过程.这个Externalizable接口扩展了Serializable,并增添了两个方法:writeExternal()和readExternal().在序列化和重新装配的过程中,会

Java序列化的机制和原理

有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java 序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一种处理对象序列化的标准机制.在这里你能学到如何序列化一个对象,什么时候需要序列化以及Java序列化的算法,我们用一个实例来示范序列化以后的字节是如何描述一个对象的信息的. 序列化的必要性

Java序列化——transient关键字和Externalizable接口

    提到Java序列化,相信大家都不陌生.我们在序列化的时候,需要将被序列化的类实现Serializable接口,这样的类在序列化时,会默认将所有的字段都序列化.那么当我们在序列化Java对象时,如果不希望对象中某些字段被序列化(如密码字段),怎么实现呢?看一个例子: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import java.io.Serializable; import java.util

Java 序列化的高级认识

引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口,使用 ObjectInputStream 和 ObjectOutputStream 进行对象的读写.然而在有些情况下,光知道这些还远远不够,文章列举了笔者遇到的一些真实情境,它们与 Java 序列化相关,通过分析情境出现的原因,使读者轻松牢记 Java 序列化中的一些高级认识. ----------

java序列化不能序列化static变量吗?为什么?能不能举个例子

问题描述 java序列化不能序列化static变量吗?为什么?能不能举个例子 java序列化不能序列化static变量吗?为什么?能不能举个例子 解决方案 你是怎么"序列化"的?如果你自己反射,并且将静态属性的变量存下来,再恢复,这个当然会改变的.但是直接对对象实例序列化是不包括静态成员的. 解决方案二: static成员不属于对象实例,没办法序列化.因为没办法,就不举例了. 解决方案三: 支持2楼解释..............

java 序列化

1.java序列化的作用 序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得.  序列化分为两大部分:序列化和反序列化.序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输.反序列化就是打开字节流并重构对象.对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据.恢复数据要求有恢复数据的对象实例  序列化的什么特点:  如果某个类能够被序列化,其子类也可以被序列化.声明为static和transient类型的成员数据不能被序列化.因为sta