|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
对用户来说可预见费用、节约费用,可以做到花少钱办大事。由于省去了购买软件和硬件等的前期费用,用户可以租用较高级的应用软件。ASP的收费是根据软件的类型、客制化程度、用户数量、服务期限来定的,对客户来说这笔费用是可以预见的。方便于客户应用软件的升级。办事器|伸缩|功能 办事器功能和可伸缩性杀手
George V. Reilly
微软公司
2月22, 1999
目次
叙言
使用法式办事器
IIS的天真性和功能
抹杀办事器功能的十条戒律
结论
--------------------------------------------------------------------------------
叙言
如今,办事器功能成绩是很多书写桌面使用法式的人所要面临的成绩。组件对象模子(Component Object Model,COM)和Component ware的胜利发生了一个意想不到的了局,这就是假如利用像ASP(IIS的一个扩大)如许的使用法式办事器,就不必编写主机代码了,其实之前的主机代码都不是在真实的办事器情况下编写的。桌面情况和办事器情况之间有很多主要的分歧,这些分歧会在功能上发生不成展望的影响。
桌面使用法式办事器
影响桌面使用法式功能的要素是尽人皆知的。长指令途径意味着更慢的代码,这是功能方面的一个次要缺点。利用大批资本会使使用法式变得加倍痴肥,如许体系中的其他使用法式可用的资本就会更少。减慢启动工夫会激愤用户。太多的运转设置会使机械的页毛病率增高,使它们变慢并且反应愚钝。办事器使用法式也常遭到这些要素影响,别的还有一些其他要素引见以下:
凡是,办事器使用法式同时处置的客户没有几百也有几十。对桌面使用法式来讲,假如能在1/10秒内对用户做出反响就算是很快的了。假定一个操作需求整整100ms的话,那末这个使用法式在一秒中只能停止10个操作。大多半办事器使用法式需求比每秒钟十次恳求大很多的通量。高延迟工夫收集(延迟工夫=动静的传输工夫)加长了反响工夫,这就需求办事器的反响更快以知足请求。
办事器使用法式常常处置大批的数据设置。效力低下的,特别是那些华侈运转工夫的办法,是不克不及用于处置上百万条数据的。
办事器机械比桌面机械更壮大。办事器机械有更多的内存,更大的磁盘,更快的CPUs,而且凡是有多个处置器。然而这些依然不敷。桌面机械处置的是零散的突发性营业,大局部工夫是余暇的,而办事器的负载是接二连三的。办事器机械很昂贵,必需运转得很好才行。
办事器使用法式需求具有以月盘算的正常运转工夫。过了一段工夫后,办事器的功能必需不会因为资本泄漏或 cruft(一种需求周期性排除的数据布局和统计了局)的储蓄积累而下降。
大多半办事器使用法式都需求采取多线程布局。思索一个一次只处置一个恳求。而将大局部工夫都化在I/O上的单线程办事器,如许的功能是很难让人承受的。线程池可以使用其他余暇的处置器时钟周期同时处置几个恳求。为了充实使用多处置器体系,办事器使用法式必需是多线程的。不幸的是,多线程使用法式很难编写,很难调试,并且很难运转得好,特别是在多处置器体系中。然而一旦准确地失掉它,其功能会远远超越一样的单线程使用法式,从这一点来讲,利用多线程使用法式仍是值得的。
单线程使用法式绝对复杂,很轻易了解:法式中某一时辰只要一个事务产生。在多
线程使用法式中,并刊行为招致庞杂的互相感化,其影响很难展望。别的,这些相
互感化,不论是否是灾害性的,都很难再生。桌面使用法式很少有多于一个线程
的,即便有,这些线程也只是用于分立的后台营业,例如打印。
IIS的天真性和功能
Internet Information Server(IIS)是一个使用法式办事器。在良多方面,它像是一个虚拟操作体系,由于有很多ASP和ISAPI使用法式在处置距离中运转。
IIS利用一个I/O线程池来处置一切到来的恳求。对静态文件(.htm,.jpg等文件)的恳求会即刻失掉知足,而对静态内容的恳求被分拨到恰当的ISAPI扩大静态毗连库。ASP扩大使用一个工人线程池运转ASP页。由于ASP是基于COM的,所以一切组件都是在咱们的处置过程当中履行的。这是一个利害掺半的工作。它对开辟者来讲是好极了,由于它答应组件的复杂重用,使ASP十分天真,因而使ASP和IIS十分胜利。然而,这个天真性招致了功能成绩。由于很多组件是为桌面体系编写的,而且很多专门为ASP创立的组件是由那些不是非常会写高功能办事器组件的人编写的。
对ISAPI扩大和过滤器也是一样。分歧组件之间及统一组件的分歧实例中都存在着严重的互相影响。
上面的一切申明都合用于IIS,个中的大多半也合用于其他办事器使用法式。
抹杀办事器功能的10条戒律
上面的每条戒律都将无效地影响代码的功能和可伸缩性。换句话说,尽量不要照着戒律去做!上面,我将注释若何损坏他们以便进步功能和可伸缩性。
应当分派和释放多个对象
你应当尽可能防止过量分派内存,由于内存分派多是价值奋发的。释放内存块能够更昂贵,由于大多半分派算符老是妄图毗连邻近的已释放的内存块成为更大的块。直到Windows NT? 4.0 service pack 4.0,在多线程处置中,体系堆凡是都运转得很糟。堆被一个全局锁回护,而且在多处置器体系上是不成扩大的。
不该该思索利用处置器高速缓存
大多半人都晓得由虚拟内存子体系招致的hard 页毛病价值很高,最好防止。然而很多人以为其他内存会见办法没有甚么区分。自从80486今后,这一概念就不合错误了。古代的CPUs比RAM要快很多,RAM最少需求两级内存缓存 ,高速L1 缓存能保留8KB数据和8KB指令,而较慢的L2 缓存能保留几百KB的数据和代码,这些数据和代码夹杂在一同。L1 缓存中内存区域的一个援用需求一个时钟周期,L2 缓存的援用需求4到7个时钟周期,而主内存的援用需求很多个处置器时钟周期。后一数字不久将会超越100个时钟周期。在很多方面,缓存像一个小型的,高速的,虚拟内存体系。
至于弛缓存有关的根基内存单位不是字节而是缓存列。Pentium 缓存列有32个字节宽。Alpha 缓存列有64个字节宽。这意味着在L1 缓存中只要512个slot给代码和数据。假如多个数据一同利用(工夫地位)而其实不存储在一同(空间地位),功能会很差。数组的空间地位很好,而互相毗连的列表和其他基于指针的数据布局的地位常常很差。
把数据打包到统一个缓存列中凡是会有益于进步功能,然而它也会损坏多处置器体系的功能。内存子体系很难调和处置器间的缓存。假如一个被一切处置器利用的只读数据,和一个由一个处置器利用并频仍更新的数据同享一个缓存 列,那末缓存将会消费很长工夫更新这个缓存列的拷贝。这个Ping-Pong高速游戏凡是被称为"缓存 sloshing"。假如只读数据在一个分歧的缓存 列中,就能够防止sloshing。
对代码停止空间优化比停止速度优化效力更高。代码越少,代码所占的页也越少,如许需求的运转设置和发生的页毛病也会更少,同时占有的缓存 列也会更少。但是,某些中心函数应当停止速度优化。可以使用profiler去辨认这些函数。
决不要缓存频仍利用的数据。
软件缓存可以被各类使用法式利用。当一个盘算价值很高时,你会保留了局的一个拷贝。这是一个典范的时空折衷办法:就义一些存储空间以节俭工夫。假如做得好,这类办法能够十分无效。
你必需准确地停止缓存。假如缓存了毛病数据,就会华侈存储空间。假如缓存得太多,其他操作可使用的内存将会很少。假如缓存得太少,效力又会很低,由于你必需从头盘算被缓存 漏掉的数据。假如将工夫敏感数据缓存得工夫太长,这些数据将会过时。普通,办事器更关怀的是速度而不是空间,所以他们要比桌面体系停止更多的缓存。必定要按期去除不必的缓存,不然将会有运转设置成绩。
应当创立多个线程,越多越好。
调剂办事器中起感化的线程数量是很主要的。假如线程是I/O-bound的,将会消费良多工夫用来守候I/O的完成-一个被壅塞的线程就是一个不做任何有效任务的线程。到场额定的线程可以增添通量,然而到场过量的线程将会下降办事器的功能,由于高低文互换将会成为一个严重的overhead。高低文互换速度应当低的缘由有三个:高低文互换是纯真的overhead,对使用法式的任务没有任何好处;高低文互换用尽了名贵的时钟周期;最糟的是,高低文互换将处置器的缓存填满了没用的数据,交换这些数据是价值奋发的。
有良多工作是依托你的线程化布局的。每一个客户端一个线程是相对不适合的。由于关于大批用户端,它的扩大性欠好。高低文互换变得难以忍耐,Windows NT用尽了资本。线程池模子会任务得更好,在这类办法中一个工人线程池将处置一条恳求列,由于Windows 2000供应了响应的APIs,如QueueUserWorkItem。
应当对数据布局利用全局锁
使数据线程平安的最复杂办法是把它套上一把大锁。为复杂起见,一切的器材都用统一把锁。这类办法会有一个成绩:序列化。为了失掉锁,每个要处置数据的线程都必需列队等待。假如线程被一把锁壅塞,它没有在做任何有效的事。当办事器的负载较轻时,这个成绩其实不罕见,由于一次能够只要一个线程需求锁。在负载很重的情形下,对锁的剧烈争取能够就会成为一个大成绩。
假想在多车道高速公路上产生了一个不测变乱,这条高速公路上的一切车辆都被转向一条狭小的路途。假如车辆很少,这一转换对交通流的速度的影响可以疏忽。假如车辆良多,当车辆渐渐并入那条单通道时,交通壅塞会延长几英里。
有几种手艺可以削减锁竞争。
・ 不要过度回护,也就是说,不长短常需要不要锁住数据。只要需求时才去持有锁,并且工夫不要太长。不要在大段代码四周或频仍履行的代码中没需要地利用锁,这一点很主要。
・ 对数据停止朋分,使它可以用一套自力的锁回护。例如,一个符号表可以按标识符的第一个字母朋分,如许在修正名字以Q开首的符号的值时,就不会去读名字以H开首的符号的值。
・ 利用APIs的Interlocked 系列(InterlockedIncrement,InterlockedCompareExchangePointer等)主动修正数据而不需求锁。
・ 当数据不是常常被修正时可使用多读者/单作者(multi-reader/single-writer)锁。你将取得更好的并发性,虽然锁操作的价值将更高而且你能够会冒饿逝世作者的风险。
・ 在关头局部利用轮回计数器。拜见Windows NT 4.0 service pack 3中的SetCriticalSectionSpinCount API。
・ 假如你不克不及失掉锁,利用TryEnte</p> asp可以轻松地实现对页面内容的动态控制,根据不同的浏览者,显示不同的页面内容。而浏览者一点觉察不出来,就像为他专门制作的页面一样。使用各种各样的组件,asp可以完成无比强大的功能。 |
|