2017-03-10 8 views
2

IISがカスタムエラーハンドラとして定義された従来のASPスクリプトを同期して単一のスレッドで実行することが判明しました。 これは非常に遅いです。私はIIS Expressの10.0によって提供index.aspを持ってIISがカスタムエラーハンドラを単一スレッドで同期的に実行する

は、ここに私の設定です。 index.aspには、3つのイメージ要素(<img src="..">)があり、IISが各タグに対してカスタム400エラーハンドラーを呼び出すようにします。

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 

:ここ

Log2File "start" 
call main 
Log2File "end" 

とは、3つの呼び出しのための時間があるよう

ハンドラがapplicationhost.config

<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath" errorMode="Custom" > 
    <error statusCode="404" path="/handler.asp" responseMode="ExecuteURL" /> 

として

handler.aspで定義されているが、その開始時刻と終了時刻を記録しますハンドラの実行はシーケンシャルであることがわかります。最初のst opsが3:16:12 に、2番目が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つ作成されていません。 そして、この1つのスレッドは、それらを順番に実行しました。

だから、私の質問は:

どのように私はIISがカスタムエラーハンドラの実行を並列化することができますか?

UPDATE

私は小さなテストをしました。私はindex.aspに破損したSRCと5つのiframeを置く:ローカルホスト上

<% 
    Dim http, url 
    Set http = Server.CreateObject("MSXML2.ServerXMLHTTP") 
    url = "http://localhost:10000/" 
    http.open "GET", url, False 
    http.send() 
    Response.Write(http.ResponseText) 
    %> 

<!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> 

は、その後、私は400エラーを処理するために、従来のASPを使用し

: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); 

は、クロームのネットワークコンソールが表示するものです

ここでは、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

エラーページの実行に9秒かかることは問題ではないと思いませんか?それをより速く(<100ms)し、同期実行について心配しないでください。私はあなたが実行モデルを変更できるかどうかは疑問です。 –

+0

@PeterHahndorfエラーハンドラのジョブには時間がかかりますが、残念ながら9秒は上限ではありません。カスタムエラーハンドラとしてasync httpハンドラ(https://msdn.microsoft.com/en-us/library/ms227433.aspx)の実装が問題を解決できるかどうか疑問に思っていますか? – rlib

答えて

1

は、私はあなたのため、セッションの問題を持っていると思います。セッションは、aspまたはasp.netであれ、同期しています。開始要求イベントで初期化/ロックされ、要求終了後に解放されます。したがって、非同期で動作させる場合は、セッションレスでリクエストを行う必要があります。あるいは、バックグラウンドジョブやハンドラのような別のアプローチを使用することもできますが、セッションも使用しません。

+0

しかし、なぜIISが古典的なaspエラーハンドラで5つのセッションの5つのスレッドを開き、5つのスレッドを開いてasp.netのために並列にリクエストを処理しないのですか?上のasp.netスクリプトではセッションを設定しませんか?そして、どのように私は古典的なASPでセッションを無効にするのですか? – rlib

+0

ブラウザに同じセッションCookieがあり、同じセッションの5つの要求がすべて識別されるためです。 <%@ EnableSessionState = False%> https://support.microsoft.com/ru-hel/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}ではないディレクトリ

ないが、その後、書き換え、これを使用するアクションを変更します

/handler.asp?path={R:0}

handler.aspは、これらの不足しているファイルを処理するファイルです:リライトURLとして。

あなたのhandler.aspでget path = request( "path")を実行し、好きなように処理します。

カスタムエラーモジュールは長年にわたって更新されておらず、URLリライトモジュールはずっと新しいです。また、マルチスレッド化されています。

+0

悲しいことに、あなたのソリューションを適用することはできません:カスタムエラーハンドラだけが使用できます。 また、UPDATEで述べたように、ASP.NETコードで記述されたカスタムエラーハンドラはマルチスレッドです。あなたはこれにいくつかの参照を提供することができます: "カスタムエラーモジュールは長年更新されていません"? – rlib

関連する問題