我发现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.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处理程序。
有没有办法改善它?
你不觉得问题是你的错误页面需要9sec执行吗?让它更快(<100ms),不用担心同步执行。我怀疑你可以改变执行模式。 –
@PeterHahndorf错误处理程序中的工作需要很长时间,可悲的是,9秒不是上限。我是.NET新手,想知道async http handler(https://msdn.microsoft.com/zh-cn/library/ms227433.aspx)作为自定义错误处理程序的实现是否可以解决问题? – rlib