我發現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