处理asp请求
图1说明了一个典型的asp请求的处理流程。该请求由wam对象进行初始化处理。该wam对象再把它发送给asp-runtime。asp-runtime通过创建一个内部页面对象对其进行响应。
wam对象是一个自由线程对象。当它调用诸如asp.dll的isapi扩展时,它使用由iis-runtime维护的线程池所分配的mta模型的线程。
创建isapi扩展时面对的一个棘手的问题是,如何处理由这一mta线程池所带来的线程并发与同步的问题。asp-runtime通过在运行asp脚本前把每个asp请求切换至一个单线程单元(sta),从而使问题得到简化。asp-runtime管理一个独立的sta辅助线程池(在后台,asp实际上通过使用com+线程池来实现这一点)。asp设计师创建了这种线程池方案,以在并发和资源利用之间提供一种优化平衡,同时消除对程序员实现同步的需要。
图 1
图2说明了asp-runtime是怎样把每个请求从mta线程切换到sta线程的。asp-runtime调度机制把每个请求都放到一个中央请求队列中。由asp管理的线程池中的sta线程监视该队列并以先进先出方式处理请求。注意,这一线程池的大小是动态变化的。asp-runtime在通信高峰期会产生额外的线程,而在通信较少时释放线程。
图 2
切换到sta线程有效地解决了并发性问题,但是这样对于性能也有明显的影响。在一个单独的mta线程中队每个请求进行处理的isapi扩展dll都能提供更快的响应时间。
iis提供了一种方法以对sta线程池和请求队列的最大尺寸进行设置。线程池的大小由iis元数据库中aspprocessorthreadmax主键控制。该主键的缺省设置是每进程每处理器25(评论:此数字最好能找到微软的相关文档证明一下。有人说这个数目是10个/cpu)。也就是说,在一台四处理器计算机中,每个处理asp的进程可以最多有100个辅助线程。除非对调整线程池的相关问题已经考虑成熟,否则应该避免改变该键值。注意,你不能使用internet server manager来改变这个设置。必须使用管理脚本或者vb应用来进行修改。
iis为asp请求队列设置了一个最大容量。缺省情况下,asp-runtime允许队列最多容纳3000个请求(微软的另一篇文档指出,这个队列只能容纳500个请求)。一旦超出,后来进入的asp请求就会被拒绝,返回错误信息为“server too busy”。
可以使用iis管理对象和adsi来编程修改aspprocessorthreadmax主键和asprequestqueuemax主键。例如,在一个standard exe项目中,引用active ds类型库,编写如下代码:
dim mywebserver as activeds.iads
set mywebserver = getoject(“iis://localhost/w3svc”)
mywebserver.put “aspprocessorthreadmax”, 30
mywebserver.put “asprequestqueuemax”, 1500
mywebserver.setinfo
下面简单总结一下在单处理器计算机上以缺省方式安装的iis中,asp线程池是怎么工作的。该线程池对于每个处理器有25个sta辅助线程可用。当一个请求到达时,就被放到请求队列中,asp-runtime从线程池中调度一个空闲sta线程,如果存在一个可用的话(注意,这种方案允许线程池中的任何线程都可以对请求进行处理)。如果没有空闲的辅助线程,请求就加入队列。只要队列没有达到缺省最大容量,所有请求都将得到处理。
来自ted pattison的《programming distributed application with visual basic 6.0》
