我发现IIS在单个线程中同步执行定义为自定义错误处理程序的经典ASP脚本。 这是非常慢的。
这是我的设置:
我有IIS Express 10.0提供的index.asp
。 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
我们可以看到处理程序的执行是顺序执行的:第一个停止于3:16:12
第二个开始于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并行执行自定义错误处理程序?
更新
我做了一个小测试。我将src损坏的5个iframe放在
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上运行的服务器的响应延迟为10秒:
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.config定义):
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处理程序上。
有办法改善吗?
最佳答案
我认为您是因为Session而遇到问题。无论是asp还是asp.net, session 都是同步的,它在begin request事件中初始化/锁定,并且仅在请求结束后才释放。因此,如果您想使请求异步运行,则需要使请求变得无 session 。或者,您可以使用其他方法,例如后台作业或处理程序,但它们也不会使用 session 。
关于multithreading - IIS在单个线程中同步执行自定义错误处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42708771/