2017-03-10 67 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