multithreading - IIS在单个线程中同步执行自定义错误处理程序

标签 multithreading iis asp-classic

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

这是我的设置:

我有IIS Express 10.0提供的index.aspindex.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 Classic

现在,我使用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.NET

因此,问题出在经典ASP处理程序上。

有办法改善吗?

最佳答案

我认为您是因为Session而遇到问题。无论是asp还是asp.net, session 都是同步的,它在begin request事件中初始化/锁定,并且仅在请求结束后才释放。因此,如果您想使请求异步运行,则需要使请求变得无 session 。或者,您可以使用其他方法,例如后台作业或处理程序,但它们也不会使用 session 。

关于multithreading - IIS在单个线程中同步执行自定义错误处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42708771/

相关文章:

c++ - 使用多线程迭代未排序的数据结构(如数组、树)可以使迭代更快吗?

multithreading - GThread中的g_timeout_add

performance - 如何使用性能监视器查看当前用户?

php - PHP 中的并行处理 - 你是怎么做到的?

java - 假装同步的异步 websocket 机制

Eclipse – ASP 经典插件

asp-classic - Request.Form 有时会返回复选框的值,有时不会

jquery - ASP .Net jQuery DropDownList 更改事件

Python导入错误 "DLL load failed"| Python

c# - 如何在 asp.net 应用程序中有多个 bin 文件夹?