Pb是很好的开发数据库应用的软件,pb8以前可以用其自带的Transport 对象实现三层结构,但pb8以后简单好用的只有easerver,但据说这是很贵的软件,就是盗版也不好。Pb11可直接将nvo发布为webservice,这对pb熟手来说是一个很好的事情,可是,习惯了C/S结构开发的思路,用webservice,数据库连接会不会过于频繁?用pb内部的数据库连接方式有没有连接池? Webservice连接性能到底怎样?等等问题,是每个从C/S编程转向B/S编程或采取三层结构编程的人都会涉及到的。下面就以pb11写webservicepb8调用对其连接池及性能进行测试。
1、单客户端、不连接数据库、pb写的webservice的响应速度
测试方案:
Pb11 webservice函数of_adder(),累加当前秒钟值 10000 次的结果。客户端pb8,在不同电脑上,调用1000次。
Webservice代码如下图。
Pb11 webservice函数of_adder(),累加当前秒钟值 10000 次的结果。客户端pb8,在不同电脑上,调用1000次。
Webservice代码如下图。
测试结果:
耗时25秒,无数据库连接会话。
2、单客户端、连接数据库、pb的webservice的响应速度
测试方案1:
函数f_connect()连接数据库,函数of_getdbhandle()返回当前连接数据库事务对象的句柄,客户端保持webservice连接(每次调用不重新初始化),webservice保持数据库连接不断开。客户端pb8,在不同电脑上,调用100次。
客户端代码如下:
string ls_wsdl
long i, j
long nums
setpointer(hourglass!)
/
/连接系统库
SQLCA.DBMS = "IN7 INFORMIX-7"
SQLCA.Database = "sysmaster"
SQLCA.UserId = "informix"
SQLCA.DBPass = wf_sa_pwd()
SQLCA.ServerName = "192.168.0.1@server1"
SQLCA.AutoCommit = False
SQLCA.DBParm = "CommitOnDisconnect='No',DisableBind=1"
connect using sqlca ;
if sqlca.sqlcode <> 0 then
messagebox('错误',"连接系统库失败",stopsign!)
return
end if
SQLCA.DBMS = "IN7 INFORMIX-7"
SQLCA.Database = "sysmaster"
SQLCA.UserId = "informix"
SQLCA.DBPass = wf_sa_pwd()
SQLCA.ServerName = "192.168.0.1@server1"
SQLCA.AutoCommit = False
SQLCA.DBParm = "CommitOnDisconnect='No',DisableBind=1"
connect using sqlca ;
if sqlca.sqlcode <> 0 then
messagebox('错误',"连接系统库失败",stopsign!)
return
end if
time t1,t2
t1 = now()
t1 = now()
= ''
//循环调用
for j = 1 to long()
yield()
if not isvalid(w_1) then exit
for j = 1 to long()
yield()
if not isvalid(w_1) then exit
= string(j)
//未创建 webservice连接 则创建 ( ws为窗口实例变量 )
if not isvalid(ws) then
ws = Create oleobject
i = ws.ConnectToNewObject("MSSOAP.SoapClient30")
if i <> 0 then
destroy ws
messagebox('提示 ','请检查是否安装了SoapSDK3.0和XML4.0', exclamation!)
//未创建 webservice连接 则创建 ( ws为窗口实例变量 )
if not isvalid(ws) then
ws = Create oleobject
i = ws.ConnectToNewObject("MSSOAP.SoapClient30")
if i <> 0 then
destroy ws
messagebox('提示 ','请检查是否安装了SoapSDK3.0和XML4.0', exclamation!)
return
end if
ws.ClientProperty("ServerHTTPRequest",true)
ls_wsdl = profilestring("soap.ini", "soap", "url", "")
ws.mssoapinit(ls_wsdl)
ws.ConnectorProperty("Timeout",180000)
end if
//webservice 方法中每次连接数据库且用完即断开
= ws.of_getdbhandle() //webservice方法连接数据库时的dbhandle()
// = ws.of_adder()
/
end if
ws.ClientProperty("ServerHTTPRequest",true)
ls_wsdl = profilestring("soap.ini", "soap", "url", "")
ws.mssoapinit(ls_wsdl)
ws.ConnectorProperty("Timeout",180000)
end if
//webservice 方法中每次连接数据库且用完即断开
= ws.of_getdbhandle() //webservice方法连接数据库时的dbhandle()
// = ws.of_adder()
/
/从 sysmaster 库中查看 webservice 中每次连接是否都释放了,SessionID 是否保持一个
// myvpc 为webservice所在主机名(web服务器主机名)
select count(*) into :nums from syssessions where hostname = 'myvpc' using sqlca ;
if not isvalid(w_1) then exit
if sqlca.sqlcode =0 then
st_ = string(nums) //循环第j次时连接数据库的sid数
if long(st_) > nums then st_ = string(nums)
if long(st_) < nums then st_ = string(nums)
end if
if not isvalid(w_1) then exit
next
// myvpc 为webservice所在主机名(web服务器主机名)
select count(*) into :nums from syssessions where hostname = 'myvpc' using sqlca ;
if not isvalid(w_1) then exit
if sqlca.sqlcode =0 then
st_ = string(nums) //循环第j次时连接数据库的sid数
if long(st_) > nums then st_ = string(nums)
if long(st_) < nums then st_ = string(nums)
end if
if not isvalid(w_1) then exit
next
t2 = now()
= string(SecondsAfter(t1, t2))
if isvalid(sqlca) then
disconnect using sqlca ;
end if
if isvalid(ws) then
ws.DisconnectObject ( )
destroy ws
end if
调用webservice服务webservice代码如下图:
disconnect using sqlca ;
end if
if isvalid(ws) then
ws.DisconnectObject ( )
destroy ws
end if
调用webservice服务webservice代码如下图:
测试结果:
耗时81秒,最大SID数100,每次dbhandle均不同。且客户端退出,SID仍未释放(尽管webservice端析构函数destructor中有断开数据库连接,客户端有DisconnectObject ( )和destroy webservice连接对象。回收iis池,SID即都被释放。
耗时81秒,最大SID数100,每次dbhandle均不同。且客户端退出,SID仍未释放(尽管webservice端析构函数destructor中有断开数据库连接,客户端有DisconnectObject ( )和destroy webservice连接对象。回收iis池,SID即都被释放。
测试方案2:
同测试方案1,只是webservice函数of_getdbhandle()中每次断开连接(disconnect using sqlca;这一行的不注释)。
测试结果:
耗时85秒,最大SID数2,每次dbhandle基本相同,中途偶有变过。客户端执行完毕SID均已释放。
同测试方案1,只是webservice函数of_getdbhandle()中每次断开连接(disconnect using sqlca;这一行的不注释)。
测试结果:
耗时85秒,最大SID数2,每次dbhandle基本相同,中途偶有变过。客户端执行完毕SID均已释放。
3、多客户端、连接数据库、并发调用pb的webservice的响应速度
测试方案:
同2中“测试方案2” ,只是客户端启动4个,并发调用。
测试方案:
同2中“测试方案2” ,只是客户端启动4个,并发调用。
测试结果:
如上图,耗时平均每客户端46秒,最大SID数3,过程中有检索不到SID记录的情况,dbhandel在4个客户端中有相互变动、相同、或彼此交换等的情况。执行完毕SID均已被释放。
说明:
为保证测试准确性,每次测试前回收iis连接池,重启网站。终止客户端未正常退出进程、
为保证测试准确性,每次测试前回收iis连接池,重启网站。终止客户端未正常退出进程、
数据库连接等保持环境一致。
总结:
1、如果不涉及数据库连接,纯逻辑运算,pb8调用pb11写的webservice,速度较快。数字累加计算10000次,连续调用1000次,平均每次只需 0.025秒。
2、仅连接并断开数据库,不考察表操作,即只考察数据库即时连接与断开连接的开销时。原C/S结构下保持数据库连接直到对象退出时再断开数据库连接的思路在B/S结构下行不通,这种思路下数据库连接会不断增加,不会因对象的释放而destructor事件中断开数据库连接的代码被执行。而应该采用函数内连接并断开,即:即时连接即时断开的方式。iis会自动提供数据库连接池功能,尽管pb的webservice中采用的是pb内部的数据库连接方式,譬如I10 INFORMIX-10.0,连接池依然有效;尽管disconnect了,但是数据库连接并不一定真的断开了,可能只是释放入池中了。
3、即用即连的方式,客户端越多性能越高(未测试临界点)。4个客户端并发,每个客户端循环调用100次,平均每个客户端46秒,即平均每次调用0.46秒。单客户端调用则平均每次调用0.85秒。断开连接可能只是释放入池中,但是无其它连接请求时池中连接会真的断开,以致多个客户端比单个客户端性能更好。Iis的池可以单独定义,可以设置自动回收
1、如果不涉及数据库连接,纯逻辑运算,pb8调用pb11写的webservice,速度较快。数字累加计算10000次,连续调用1000次,平均每次只需 0.025秒。
2、仅连接并断开数据库,不考察表操作,即只考察数据库即时连接与断开连接的开销时。原C/S结构下保持数据库连接直到对象退出时再断开数据库连接的思路在B/S结构下行不通,这种思路下数据库连接会不断增加,不会因对象的释放而destructor事件中断开数据库连接的代码被执行。而应该采用函数内连接并断开,即:即时连接即时断开的方式。iis会自动提供数据库连接池功能,尽管pb的webservice中采用的是pb内部的数据库连接方式,譬如I10 INFORMIX-10.0,连接池依然有效;尽管disconnect了,但是数据库连接并不一定真的断开了,可能只是释放入池中了。
3、即用即连的方式,客户端越多性能越高(未测试临界点)。4个客户端并发,每个客户端循环调用100次,平均每个客户端46秒,即平均每次调用0.46秒。单客户端调用则平均每次调用0.85秒。断开连接可能只是释放入池中,但是无其它连接请求时池中连接会真的断开,以致多个客户端比单个客户端性能更好。Iis的池可以单独定义,可以设置自动回收
时机,回收时对客户端连接有极大影响,池设置在iis中不在weservice中也不在客户端连接设置中。
4、采用webservice方式,比C/S方式,会慢很多(未与其他三层模式比较)。Pb8以上版本开发客户端并搭建中间层应用,对于中小企业不增加投资,综合经济与技术及性能要求的情况下,webservice还是可考虑的。
4、采用webservice方式,比C/S方式,会慢很多(未与其他三层模式比较)。Pb8以上版本开发客户端并搭建中间层应用,对于中小企业不增加投资,综合经济与技术及性能要求的情况下,webservice还是可考虑的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论