论坛首页 Java企业应用论坛

Soap性能问题 Axis vs Delphi 2005

浏览 7806 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-08-07  
SOA
今天就Soap做了一个简单的测试程序,服务器端使用Axis1.2.1,客户端使用Delphi2005(使用MSXML作解析的)。在测试中发现一个性能方面的问题。

客户端和服务器端传递的对象如下
  TAddress = class(TBaseObject);
  private
    Faddress: String;
    Fcity: String;
    Fcountry: String;
    FpostalCode: String;
    Fprovince: String;
  published
    property address: String read Faddress write Faddress;
    property city: String read Fcity write Fcity;
    property country: String read Fcountry write Fcountry;
    property postalCode: String read FpostalCode write FpostalCode;
    property province: String read Fprovince write Fprovince;
  end;

  ArrayOfRoleEntity = array of TRoleEntity;      { "http://types.soap.appfuse.org" }


  // ************************************************************************ //
  // Namespace : http://types.soap.appfuse.org
  // ************************************************************************ //
  TUserEntity = class(TRemotable);
  private
    Faddress: TAddress;
    FconfirmPassword: String;
    Femail: String;
    Fenabled: Boolean;
    FfirstName: String;
    FlastName: String;
    Fpassword: String;
    FpasswordHint: String;
    FphoneNumber: String;
    Froles: ArrayOfRoleEntity;
    Fusername: String;
    Fversion: Integer;
    Fwebsite: String;
  public
    destructor Destroy; override;
  published
    property address: TAddress read Faddress write Faddress;
    property confirmPassword: String read FconfirmPassword write FconfirmPassword;
    property email: String read Femail write Femail;
    property enabled: Boolean read Fenabled write Fenabled;
    property firstName: String read FfirstName write FfirstName;
    property lastName: String read FlastName write FlastName;
    property password: String read Fpassword write Fpassword;
    property passwordHint: String read FpasswordHint write FpasswordHint;
    property phoneNumber: String read FphoneNumber write FphoneNumber;
    property roles: ArrayOfRoleEntity read Froles write Froles;
    property username: String read Fusername write Fusername;
    property version: Integer read Fversion write Fversion;
    property website: String read Fwebsite write Fwebsite;
  end;

  ArrayOfUserEntity = array of TUserEntity;   { "http://service.soap.appfuse.org" }


  // ************************************************************************ //
  // Namespace : http://types.soap.appfuse.org
  // ************************************************************************ //
  TRoleEntity = class(TRemotable);
  private
    Fdescription: String;
    Fname: String;
    Fusers: ArrayOfUserEntity;
    Fversion: Integer;
  public
    destructor Destroy; override;
  published
    property description: String read Fdescription write Fdescription;
    property name: String read Fname write Fname;
    property users: ArrayOfUserEntity read Fusers write Fusers;
    property version: Integer read Fversion write Fversion;
  end;


在测试运行中,发现如果返回用户对象(UserEntity)数组长度500个左右时,Delphi端解析XML数据流很慢(使用MSXML解析),大概需要10秒多时间。而且返回用户对象中用户角色集合一般只有一个到两个。

以前使用xml-rpc做过类似的系统,服务器端也是使用Java,客户端使用Delphi,但是系统反应速度相差一个数量级。xml-rpc解析xml数据流是直接根据字符窜解析的。

开始认为是自己的测试程序有问题,因为soap目前应用还是比较广泛的,如果性能上这么差,很难在实际项目中应用啊!后来使用日志跟踪,服务器端基本上响应没有花多少时间,主要客户端解释传递过来的数组对象时,CPU占用竟然达到100%(CPU PIII 1800 RAM 512M),解析时间一般要在10s以上。
   发表时间:2005-08-12  
今天客户端和服务器端全部修改为axis实现,测试速度还是比较满意的。我的测试结果:
测试对象
public class SOAPStruct {
    private String varString;
    private int varInt;
    private float varFloat;
    public float getVarFloat() {
        return varFloat;
    }
    public void setVarFloat(float varFloat) {
        this.varFloat = varFloat;
    }
    public int getVarInt() {
        return varInt;
    }
    public void setVarInt(int varInt) {
        this.varInt = varInt;
    }
    public String getVarString() {
        return varString;
    }
    public void setVarString(String varString) {
        this.varString = varString;
    }
}
调用Soap方法

    public SOAPStruct[] echoStructArray(SOAPStruct[] inputStructArray) throws java.rmi.RemoteException {
        return inputStructArray;
    }
测试目的
测试soap传递大容量数据响应速度
测试结果:
数组长度 100 ,Invoke 时间 2078 ms
数组长度 200 ,Invoke 时间 1937 ms
数组长度 300 ,Invoke 时间 2015 ms
数组长度 400 ,Invoke 时间 2094 ms
数组长度 500 ,Invoke 时间 2781 ms
数组长度 600 ,Invoke 时间 3000 ms
数组长度 700 ,Invoke 时间 3235 ms
数组长度 800 ,Invoke 时间 3750 ms
数组长度 900 ,Invoke 时间 4359 ms
数组长度 1000 ,Invoke 时间 4641 ms
数组长度 1100 ,Invoke 时间 5407 ms
数组长度 1200 ,Invoke 时间 7453 ms
数组长度 1300 ,Invoke 时间 6375 ms
数组长度 1400 ,Invoke 时间 7157 ms
数组长度 1500 ,Invoke 时间 7078 ms
数组长度 1600 ,Invoke 时间 8047 ms
数组长度 1700 ,Invoke 时间 8703 ms
数组长度 1800 ,Invoke 时间 9266 ms
数组长度 1900 ,Invoke 时间 10250 ms
数组长度 2000 ,Invoke 时间 10875 ms
数组长度 2100 ,Invoke 时间 10985 ms
数组长度 2200 ,Invoke 时间 14250 ms
数组长度 2300 ,Invoke 时间 12156 ms
数组长度 2400 ,Invoke 时间 13000 ms
数组长度 2500 ,Invoke 时间 13516 ms
数组长度 2600 ,Invoke 时间 15797 ms
数组长度 2700 ,Invoke 时间 15281 ms
数组长度 2800 ,Invoke 时间 16640 ms
数组长度 2900 ,Invoke 时间 18125 ms
数组长度 3000 ,Invoke 时间 19016 ms
数组长度 3100 ,Invoke 时间 21000 ms
数组长度 3200 ,Invoke 时间 19797 ms
数组长度 3300 ,Invoke 时间 19672 ms
数组长度 3400 ,Invoke 时间 21468 ms
数组长度 3500 ,Invoke 时间 21406 ms
数组长度 3600 ,Invoke 时间 22391 ms
数组长度 3700 ,Invoke 时间 24000 ms
数组长度 3800 ,Invoke 时间 24625 ms
数组长度 3900 ,Invoke 时间 24203 ms
数组长度 4000 ,Invoke 时间 26672 ms
数组长度 4100 ,Invoke 时间 25938 ms
数组长度 4200 ,Invoke 时间 27390 ms
数组长度 4300 ,Invoke 时间 29594 ms
数组长度 4400 ,Invoke 时间 29563 ms
数组长度 4500 ,Invoke 时间 30796 ms
数组长度 4600 ,Invoke 时间 31422 ms
数组长度 4700 ,Invoke 时间 32516 ms
数组长度 4800 ,Invoke 时间 34141 ms
数组长度 4900 ,Invoke 时间 34234 ms
测试环境
硬件
Soap-axis服务器 PIII 1.8G RAM 512M
Soap-axis客户端 赛扬二代 2.0G RAM 512M
软件
Tomcat 5.5.9
axis 1.2.1
jdk 1.5 update 4
0 请登录后投票
   发表时间:2005-08-28  
今天在axis中增加了一项配置:

<parameter name="sendMultiRefs" value="false"/>


delphi 端解析速度有了很大的提高,主要是采用对象引用的方式生成的soapResponse在delphi中解析会产生重复的循环,导致解析soap response数据流开销随着数组长度增长而直线增长。
0 请登录后投票
   发表时间:2005-09-02  
加入这项配置,delphi这端的代码需要重新根据wsdl生成吗?
0 请登录后投票
   发表时间:2005-09-03  
tiyi 写道
加入这项配置,delphi这端的代码需要重新根据wsdl生成吗?

客户端代码不需要修改。
0 请登录后投票
   发表时间:2006-10-25  
今天客户端和服务器端全部修改为axis实现,测试速度还是比较满意的。我的测试结果:
测试对象
public class SOAPStruct {
    private String varString;
    private int varInt;
    private float varFloat;
    public float getVarFloat() {
        return varFloat;
    }
    public void setVarFloat(float varFloat) {
        this.varFloat = varFloat;
    }
    public int getVarInt() {
        return varInt;
    }
    public void setVarInt(int varInt) {
        this.varInt = varInt;
    }
    public String getVarString() {
        return varString;
    }
    public void setVarString(String varString) {
        this.varString = varString;
    }
}
调用Soap方法

    public SOAPStruct[] echoStructArray(SOAPStruct[] inputStructArray) throws java.rmi.RemoteException {
        return inputStructArray;
    }
[

请教一个问题:用axis作为服务器,delphi作为客户端的话,如果要传递非基本类型数据,例如上面的SOAPStruct,如果在java中写入一个Bean的话,delphi客户端是否不能识别?如果想这样的话请问该如何解决?谢谢各位了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics