2017-03-10 69 views
2

我发现IIS执行的经典ASP脚本定义为自定义错误处理程序同步并在单个线程中。 这是非常慢的IIS在单个线程中同步执行自定义错误处理程序

这里是我的设置:

index.asp通过IIS快递10.0服务。 index.asp有3个图像元素(<img src="..">),这些图像元素具有断开的链接,使IIS可以为每个标记调用自定义400错误处理程序。

处理程序在applicationhost.config定义为

<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath" errorMode="Custom" > 
    <error statusCode="404" path="/handler.asp" responseMode="ExecuteURL" /> 

handler.asp记录其开始和结束时间为

Log2File "start" 
call main 
Log2File "end" 

,这里是三个调用次数:

3/10/2017 3:16:03 AM|start|http://localhost:8081/xENOjODFFUSZWDD 
10-3-2017 3:16:12|end|http://localhost:8081/xENOjODFFUSZWDD 

3/10/2017 3:16:12 AM|start|http://localhost:8081/pWEzIB25374ynkwv 
10-3-2017 3:16:20|end|http://localhost:8081/pWEzIB25374ynkwv 

3/10/2017 3:16:20 AM|start|http://localhost:8081/pMeODA30827gurud 
10-3-2017 3:16:29|end|http://localhost:8081/pMeODA30827gurud 

我们可以看到处理程序的执行是连续的:第一个st在3点16分12秒 OPS和第二开始为3点16分12秒,等

我去TraceLogFiles文件夹以查看在何时请求不存在的文件来了,也许他们接踵而来?

这里是请求的次数:

http://localhost:8081/pWEzIB25374ynkwv 
<TimeCreated SystemTime="2017-03-10T01:16:03.586Z"/> 

http://localhost:8081/pMeODA30827gurud 
<TimeCreated SystemTime="2017-03-10T01:16:03.580Z"/> 

http://localhost:8081/xENOjODFFUSZWDD 
<TimeCreated SystemTime="2017-03-10T01:16:03.586Z"/> 

我们可以看到所有的请求都几乎在同一时刻。

因此,我得出结论,请求被放入一个队列并且一个接一个地处理。没有3个线程被创建来处理3个并发请求。 而这个单线程顺序执行它们。

所以,我的问题是:

我怎样才能使IIS并行自定义错误处理程序的执行?

UPDATE

我做了一个小测试。我把5个I帧与损坏SRC上index.asp

<!DOCTYPE html> 
<html> 
<body> 
<iframe style="border: 2px solid red" width="1080" height="100" src="http://localhost:8081/none1"></iframe> 
<iframe style="border: 2px solid red" width="1080" height="100" src="http://localhost:8081/none2"></iframe> 
<iframe style="border: 2px solid red" width="1080" height="100" src="http://localhost:8081/node3"></iframe> 
<iframe style="border: 2px solid red" width="1080" height="100" src="http://localhost:8081/none4"></iframe> 
<iframe style="border: 2px solid red" width="1080" height="100" src="http://localhost:8081/none5"></iframe> 
</body> 
</html> 

然后我用传统的ASP处理400错误:

<% 
    Dim http, url 
    Set http = Server.CreateObject("MSXML2.ServerXMLHTTP") 
    url = "http://localhost:10000/" 
    http.open "GET", url, False 
    http.send() 
    Response.Write(http.ResponseText) 
    %> 

在localhost:10000运行在服务器与10secs的延迟反应:

const logger = require('log4js').getLogger(); 
const uid = require('uid'); 
let app = require('express')() 
app.get('/', (req,res)=>{ 
    let id = uid(); 
    logger.debug(`${id}: got request`); 
    setTimeout(function() { 
    logger.debug(`${id}: response sent`); 
    res.send(`${id}: All ok`); 
    }, 10000); 
}); 

console.log('Listening on 1000'); 
app.listen(10000); 

这里是Chrome浏览器的网络控制台显示:

ASP Classic

现在,我使用asp.net处理程序(我通过Web定义)。配置):

Imports System.Web 
Imports System.Net 
Imports System.IO 


Public Class MySyncHandler 
    Implements IHttpHandler 

    Private Function GetText() As String 
     Dim request As WebRequest = WebRequest.Create("http://localhost:10000/") 
     Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse) 
     Console.WriteLine(Now() & "|Got status: " & response.StatusDescription) 
     Dim dataStream As Stream = response.GetResponseStream() 
     Dim reader As New StreamReader(dataStream) 
     Dim responseFromServer As String = reader.ReadToEnd() 
     reader.Close() 
     dataStream.Close() 
     response.Close() 
     Return responseFromServer 
    End Function 

    Public Sub ProcessRequest(ByVal context As _ 
      System.Web.HttpContext) Implements _ 
      System.Web.IHttpHandler.ProcessRequest 
     Dim request As HttpRequest = context.Request 
     Dim response As HttpResponse = context.Response 
     Dim data As String = GetText() 
     response.Write("<!DOCTYPE html><html><head><meta charset='UTF-8'/></head>") 
     response.Write("<body>") 
     response.Write(data) 
     response.Write("</body>") 
     response.Write("</html>") 
    End Sub 

    Public ReadOnly Property IsReusable() As Boolean _ 
      Implements System.Web.IHttpHandler.IsReusable 
     Get 
      Return False 
     End Get 
    End Property 
End Class 

而且从网络控制台画面看起来相当好:

ASP.NET

那么,问题是传统的ASP处理程序。

有没有办法改善它?

+0

你不觉得问题是你的错误页面需要9sec执行吗?让它更快(<100ms),不用担心同步执行。我怀疑你可以改变执行模式。 –

+0

@PeterHahndorf错误处理程序中的工作需要很长时间,可悲的是,9秒不是上限。我是.NET新手,想知道async http handler(https://msdn.microsoft.com/zh-cn/library/ms227433.aspx)作为自定义错误处理程序的实现是否可以解决问题? – rlib

回答

1

我认为你有问题,因为会话。无论是asp还是asp.net,Session都是同步的,它在初始化请求事件时被初始化/锁定,并且只有在请求结束后才被释放。所以,如果你想使它们异步工作,你需要进行会话请求。或者您可以使用不同的方法,如后台作业或处理程序,但他们也不会使用会话。

+0

但为什么IIS在经典的asp错误处理程序中为5个会话打开5个线程,并打开5个线程来为asp.net并行处理请求?在上面的asp.net脚本中,我不设置会话?如何禁用经典的ASP会话? – rlib

+0

因为您在浏览器中具有相同的会话cookie,并且它标识了同一会话的所有5个请求。可以通过<%@的EnableSessionState =假%>禁用病程的它 https://support.microsoft.com/ru-ru/help/244465/how-to-turn-off-asp-session-state-in -active-server-pages-and-iis – Sergey

+0

非常感谢。这就是发生了什么事。 – rlib

0

我会用URL重写模块为这样的任务。你能够以某种方式将那些断开的链接描述为模式吗?如果没有,你可以简单地把*为图案,并添加2个条件:

{REQUEST_FILENAME}不是一个文件 {REQUEST_FILENAME}不是一个目录

,然后改变重写,并使用这个动作作为一个重写URL:

/handler.asp?path={R:0}

其中handler.asp是你的文件,将处理这些丢失的文件。

在你handler.asp得到它,只要你喜欢PATH =请求( “路径”)和过程。

自定义错误模块一直没有更新了很多年,我相信和URL重写模块是非常新的。它也是多线程的。

+0

不幸的是,我无法应用您的解决方案:只能使用自定义错误处理程序。 另外,正如我在UPDATE中所提到的,用ASP.NET代码编写的自定义错误处理程序是多线程的。您能否提供一些参考资料:“自定义错误模块多年未更新”? – rlib