编制网络程序,我一直以为isapi是效率最高的,谁有不同的看法?也请高手针对.net,java,corba等作一下对比。(300分)

  • 主题发起人 主题发起人 李衍智
  • 开始时间 开始时间

李衍智

Unregistered / Unconfirmed
GUEST, unregistred user!
如果不考虑编程的复杂度,我认为isapi是最有效率的,那位高手有不同意见,希望不吝赐教。
也请高手针对.net,java,corba等作一下对比。
 
isapi是什麼來的?
 
怎么看的多,说的少?请高手不吝赐教。
 
ms 的 internet server api.
我曾尝试过使用它来编写网站,后因别的开发项目而暂停,谈不上高见,听课!
 
isapi效率高是没有错的,但是楼主听说过ISAPI程序崩溃会连同IIS一起崩溃的。。。
ISAPI和asp.net,jsp是没法比的,有听说过哪个中大型开发软件是用ISAPI的。。。
 
.net厉害一些
 
shiningplus:
你肯定效率高就行。至于大型软件问题拿是开发难度问题。谢谢。
andy263:
据我所知厉害的顺序应该是:corba,java,.net,
 
学习。。。。。。。。。。。。。。。。。
 
几乎所有的证券行情系统都用的是isapi,特点就是快,但是要注意访问量不能过大,如果太大,就会打爆整个系统,目前,isapi是在基于容器技术中效率最高的,比asp/jsp高多了,但是经过特殊编译的servlet容器的效率跟他差不多,罪臭的就是花钱买的weblogic,websphere如果不是客户要求,我肯定不用这些公司的产品,用自己的http server多爽
 
to 李衍智:
我 也 用 isapi
 
是的,ISAPI+多线程,效率还是不错的。
 
影响分布式对象系统的性能和扩展性的关键因素是“能否控制server端所持有的分布式对象的个数”
几个术语的解释
组件对象模型:开发oo软件所遵守的规范(从开发class的programer这一方来看)
com:微软的一种组件对象模型。
微软还有一种组件对象模型,是.net。
组件对象模型的支持环境:为对象提供服务的系统级软件。
com作为组件对象模型,它的支持环境有4代:
第1代 ole,ole2
第2代 dcom
第3代 mts
第4代 com+(com plus)
注意,com plus这种支持环境也可以对.net这种组件对象模型的对象实例提供系统服务。
(也可以 说.net 的某些组件可以调用com plus的服务)
.net将淘汰com(component object model)这种组件对象模型。
但说.net将淘汰com plus是完全错误的说法,两者是有联系,但是不具备可比性。

历史
windows的单机时代,即是ole和ole2时代,当时的组件对象模型的支持环境提供的功能集中在使“遵守com的组件实现二进制代码的重用”。使用组件的programmer只用关心“得到一个功能(即接口)”,不用关心功能由哪个组件供,以及功能如何实现。

dcom作为组件对象模型的支持环境,提供的功能有限。dcom只能做到“使用组件的programmer只用关心得到一个功能,不用关心功能由哪个机器上的哪个组件供提供”。这种做法可以让熟悉ole/ole2的programmer重用以前的经验,快速掌握dcom环境。

如果用基于ole/dcom的经验开发分布式应用,问题也随之而来。
影响分布式对象系统的性能和扩展性的关键因素是“为对象提供服务的系统级软件能否控制server端所持有的分布式对象的个数”
因为有的对象占用大量的资源(内存,cpu,数据库连接),如果这种对象数量太多,服务器的效率急速下降(原因有:事物冲突,死锁,大量的线程切换,以及死掉的client没有释放资源)。服务器最终将被拖垮。想像一下:1000个client,每个client请求5个包含数据库连接 的对象的接口,那么dcom将建立5000个数据库连接,服务器绝对死翘翘。
我把这种对象称为“重型对象”
在分布式系统中,programmer应该关心和理解对象(特别是“重型对象”
)是如何被“实例化”(intstantiation)的。在单机时代,这种需求不是那么迫切。但是在在分布式系统中,仅仅关心使用接口是不够的(原因如前所讲)。
但是,微软把com的接口当作噱头说事,淡化“对象”的概念,因为没有一种编程语言从语法上直接支持com的对象(idl可能算,但是idl知识只是起到辅助c++的作用。各种面向对象语言构造对象的方式是扎根在语法中,不能“跨语言”。必须用factory 模式把实现“构造”的语义)。
dcom的陷阱。
如果用dcom开发多层应用,那么使用接口的programmer在远程机器(既是服务器)上建立重型对象的实例的方法是有讲究的。
影响“dcom如何建立一个对象(在哪个进程中?需要新建立进程吗?在哪个线程中?需要新建立线程吗?)来响应client的请求”的因素有这么几个:1对象的intstantiation属性,2对象的线程模型(sta,mta,boath),3类厂(类对象或class factory,都是一个说法)的设计方法。
解释:
对象的intstantiation属性:
dcom环境中的对象都是属于某个进程的。
如果说一个进程只能容纳某个对象的一个实例,那么这个对象的intstantiation属性被称为“single instantiate”
如果说一个进程只能容纳某个对象的多个实例,那么这个对象的intstantiation属性被称为“multiple instantiate”

当client向dcom请求一种接口时 ,dcom发生的事情如下:
if(dcom发现此次请求的是该种接口的第一次请求){
dcom将启动第一个进程xxx,在此进程中制造一个支持该接口的对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。}
else
{
if(支持该接口的对象的intstantiation属性被称为“single instantiate”){
dcom将另外启动第一个进程yyy,在此进程中“制造”一个支持该接口的对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client}
else
if(支持该接口的对象的intstantiation属性被称为“multiple instantiate”){
dcom将在进程xxx中再次“制造”一个支持该接口的对象,把该对象up cast 成接口,传(marshal,列集)给client}

基本上是这个样子。注意“制造”的方法存在于class factory中。各种framework(vc的atl,delphi 的vcl)各自的都设计了classfactory的实现方式。基本上,client每次请求一个接口,一个对象就会被实例化。client无法指定接口邦定于哪个对象的实例。而“重型对象”
对于这种classfactory默认的“制造”方法是不能容忍的。

接口的线程模型
这个概念实在是个鸡肋。不了解吧不行。因为它是com的专有概念,而且微软把它当作噱头。(作为分布式对象的使用者不应该了解这种多余的底层的琐碎的概念)。想了解,几句话又说不清,搞懂了用处又不大。
线程模型标识了com对象和client两者的线程相容性。如果client的线程模型和com对象的接口的线程模型不相容,那么com的支持环境就会调整client和com对象的接口之间的“交流”。

搞懂了用处又不大。因为多数人都使用atl或vcl开发com对象,这些framework中的设计好 的classfactory隐藏了所有细节,其中包括线程模型的差异如何影响对象的建立。对象的建立方式的差异会影响对象的表现。而在不同framework 中的classfactory中,具有相同的线程模型标识的接口,其对象的建立方式没有规定(甚至同一个framework的不同版本,对具有某种线程模型的接口的对象 有不同的建立方式)。于是线程模型对com对象的影响就非常微妙。
举个极端的例子:delphi4和delphi5中建立dcom 对象,要求intstantiation属性被称为“multiple instantiate”,线程模型为“sta”(单套间线程模型,或 single thread apartment model,都是一个意思)

d4 的classfactory是这么干的:dcom在第一个进程xxx中的主线程中直接create一个对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。

d5中classfactory是这么干的:dcom在第一个进程xxx中新建立一个线程,标识为sta 线程,在该线程中 create一个对象, 把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。

当多个client请求d4 版本的接口时,所有的com对象都在进程xxx的一个sta线程中。所有client对各自接口的调用被sta线程的message loop同步。也就是说一个client的调用会被其他client阻塞。而当多个client请求d5 版本的接口时,所有的com对象都在进程xxx都有各自的sta线程。一个client对自己接口的调用和其他client没有关系。

intstantiation属性决定一个对象在哪个进程中被实例化。而线程模型决定了client如何与com对象交流。dcom没有提到“控制server端所持有的分布式对象的个数”。

解决方法:
“控制server端所持有的分布式对象的个数”就成了dcom组件编写人员自己要操心的事情。
delphi的sample/midas/pooler目录中有一个例子。它提供了dcom环境下client之间如何“共享”对象的实例的一个方法。(说具体点:多个client如何共享数量有限的数据库连接)

当client向dcom请求一个接口时,dcom就实例化一个对象(类型为a)。每个client都有 各自的”a对象”的实例。“a对象”的intstantiation属性是“multiple instantiate”,于是所有client的“a对象”的实例都在相同的进程xxx中。同一个进程有一个heap区域,各个“a对象”的实例都可以访问这个heap区域,各个“a对象”的实例还可以访问进程xxx中中的全局变量。当client通过接口向“a对象”发消息时(就是调用接口中的函数),“a对象”自己自己什么都不做,只“传话”,把消息发给heap中的空闲的b对象”的实例。“b对象”是“重型对象”,包含数据库连接。“b对象”的实例个数可以在进程xxx的初始化过程中指定。这样就控制了服务器上“重型对象”的个数。如果heap中没有空闲的“b对象”(都在工作中,个数达到上限),那么“a对象”将等待,直到找到可用 的“b对象”,这个过程中,client也在等待。

大致上就是这个样子。其他细节方面:1 “b对象”的实例放在链表中管理。 2“b对象”的方法要用critical sectiom(临界区域)保护。3“a对象”必须是无状态的。
这个例子还不完善,服务器不能识别“死掉”的client所占用的资源。长时间运行后,所有 的“b对象”可能都会处于“busy”状态,被“死掉”的client所占用 。系统就不能正常工作了。要想把这个例子实用化,还要加很多代码。

这是borland的做法 。微软也有相似的方法,sql server的ado驱动自带pooler功能,原理也差不多(驱动编写人员辛苦了。如果驱动不带pooler功能 ,使用人员就辛苦了 )。

dcom结论
dcom没有提到“控制server端所持有的分布式对象的个数”。要做到这个功能,编写 组件的programmer自己必须处理很多细节。设计一个“重型对象”,用dcom实现时,必须写2个class,一个代理(指逻辑功能代理,即a对象,不是指dcom中的proxy和stub),一个实现(b对象),还要注意保护代理和实现之间的交流,并防止资源泄露。用dcom实现“重型对象”是非常烦琐的。

complus的进化:
complus提供的服务要比dcom的多。重点在:pooler和jita(just in time activate)。jita可以把对象的实例化从client请求接口的时刻延迟到client向对象发消息的时刻,节省了内存。com plus的内置的pooler功能简化了开发,提高了可靠性。在complus 环境中,client可以直接通过cocreateinstence请求一个“重型对象”的接口,并查看返回值,看看是超时还是成功。比dcom轻松 许多。



 
程序界面 PHP ASP CGI NSAPI ISAPI
操作系统 均可 Win32 均可 均可 Win32
Web服务器 数种 IIS 均可 Netscape Server IIS
执行效率 快 快 慢 极快 极快
稳定性 佳 中等 最高 差 差
开发时间 短 短 中等 长 长
修改时间 短 短 中等 长 长
程序语言 PHP VB 不限 C/C++ C/Delphi
网页结合 佳 佳 差 差 差
学习门槛 低 低 高 极高 高
函数支持 多 少 不定 中等 少
系统安全 佳 极差 最佳 佳 尚可
使用网站 超多 多 多 极少 少
改版速度 快 慢 无 慢 慢
 
isapi,执行效率非常好,但是开发效率很底,问量不能过大,而且“重型资源”的共享都得手动完成,太烦琐。
com plus的效率应该和isapi有一比,而且可以限制“重型资源”的个数,防止服务器被拖垮。
 
谢谢各位:
苍蝇拍子:
还有些不明白,访问量过大,最大多大?硬件改进是否有用。不同模块用不同isapi是否有缓解。
关于容器技术,请指点。
zzsczz:谢谢,还得仔细看。
xly133:很好。
 
zzsczz:天,可能我忽略了。
 
但是isapi只能在Windows上运行,我不知道哪个大网站是跑在Windows平台上的。
 
to 李衍智
简单一点:
开发一个要连接数据库的web应用,
如果只用isapi,每个client都有一个线程,在该线程中建立数据库一个连接。
2000个client就要2000个数据库连接。数据库服务器就垮了。
web服务器上,windows要管理2000个线程,当物理内存不足时,线程切换时要和在虚拟内存和物理内存之间搬运数据,2000个线程并发,搬运频率非常高,产生“thread thrash”,web服务器忙都忙死了。
每个client的连接和退出,服务器都会产生,初始化,执行,结束一个线程,也很浪费

如果在isapi中把“重型资源”共享保护,要手工写很多代码。
可以把“重型资源”写到com 组件中(符合com+的规范,“重型资源”可以享受jita,pooler,事务等高级服务),在isapi模块中调用这些组件。这样系统的运行效率和开发效率都很高,而且扩展性会提高
 
zzsczz:
原来也考虑过com+,但没使用,我现在试一下,如果可以,当然会比isapi好。
我在写三层程序,“重型资源”可以利用存储过程,不会存在重型资源(事实上我也不会允许它存在)。
按理说我的程序是无状态的,线程用毕就应释放,但我就是这里不敢肯定,因此提出问题。
 
存储过程也要建立连接把???如果一个client建立一个连接,数据库受得了吗?
数据库支持的存储过程的并发数目有限制没有啊??如果有,就共享保护。。

设计的好,应该达到下面的标准: 1200人在线,每秒200个事务。。。(p3 1G HZ,RAM 1G SDRAM)
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部