9

理論的には、非常に重い処理を実行するページ/コントローラーアクションがWebサイトにあるとしましょう。操作が完了するまで約10秒かかります。

ここで、.NETのoutputcacheメカニズムを使用して15分間キャッシュします(たとえば、使用します[OutputCache(Duration = 900)])。15分後にキャッシュの有効期限が切れ、100人のユーザーが10秒以内にページを再度要求するとどうなりますか。重い処理?

  1. 重い作業は初めて行われるだけで、他の99人のユーザーがキャッシュ結果を取得できるようにいくつかのロックメカニズムがあります
  2. 重い作業は100回実行されます(最大100 * 10秒かかる可能性があるため、サーバーは機能しなくなります)

簡単な質問かもしれませんが、100%確信はありません。私はそれがナンバーワンであることを願っています:-)

ありがとう!

4

5 に答える 5

4

それは、IISをどのように構成したかによって異なります。ワーカースレッドが100未満(たとえば50)の場合、「重い処理」が50回実行され、サーバーが機能しなくなり、残りの50のリクエストがキャッシュから処理されます。

ただし、キャッシュされたアクションの結果には「ロックメカニズム」はありません。ほとんどの場合、それは逆効果になります。

編集:私はこれが真実であると信じています、しかしニックのテストはそうではないと言います、そして私は今テストする時間がありません。自分で試してみてください!ただし、残りの答えは上記に依存していません。それがより重要だと思います。

ただし、一般的に言えば、キャッシュされているかどうかに関係なく、Webリクエストが返されるまでに10秒かかることはありません。もし私があなたの立場にあったとしたら、私はどういうわけかリクエストの難しい部分を事前に計算することを検討するでしょう。HTMLをキャッシュしたい場合は、アクションの結果をキャッシュすることもできますが、問題はそれよりもいくらか大きいようです。

非同期コントローラーを検討することもできます。最後に、IISとASP.NET MVCはこの重い計算をロックしませんが、ロックする可能性があることに注意してください。非同期コントローラーを計算のロックと組み合わせて使用​​すると、要求している動作を効果的に得ることができます。あなたが何をしているのかをもっと知らなければ、それが最善の解決策であるかどうかは本当に言えません。

于 2010-01-29T14:26:38.390 に答える
3

簡単なテストを行って、ここでロックしているようです:

<%@ OutputCache Duration="10" VaryByParam="*" %>

protected void Page_Load(object sender, EventArgs e)
{
    System.Threading.Thread.Sleep(new Random().Next(1000, 30000));
}

最初のページは、スリープ状態のままであっても、そこでブレークポイントにヒットします... Page_Load メソッドで他のリクエストがブレークポイントにヒットすることはありません...最初のページが完了するのを待ち、そのページをリクエストしたすべての人にその結果を返します。

注: これは、Web フォームのシナリオでテストする方が簡単でしたが、これがフレームワークの共有側面であることを考えると、MVC で同じテストを実行して同じ結果を得ることができます。

別のテスト方法を次に示します。

<asp:Literal ID="litCount" runat="server" />

public static int Count = 0;

protected void Page_Load(object sender, EventArgs e)
{
  litCount.Text = Count++.ToString();
  System.Threading.Thread.Sleep(10000);
}

最初のリクエストがスリープ状態になっている間にキューに入れられたすべてのページは、同じカウント出力を持ちます。

于 2010-01-29T14:31:52.867 に答える
1

役立つかもしれない小さなテストを作成しました。私が発見したのは、キャッシュされていないリクエストがブロックされず、キャッシュの有効期限が切れてタスクが完了する前に受信した各リクエストがそのタスクをトリガーすることだと思います。

たとえば、以下のコードは、Cassini を使用したシステムで約 6 ~ 9 秒かかります。約 2 秒間隔で 2 つのリクエストを送信すると (つまり、2 つのブラウザ タブ)、両方が一意の結果を受け取ります。終了する最後の要求は、後続の要求のためにキャッシュされる応答でもあります。

// CachedController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace HttpCacheTest.Controllers
{
    public class CachedController : Controller
    {
        //
        // GET: /Cached/

        [OutputCache(Duration=20, VaryByParam="*")]
        public ActionResult Index()
        {
            var start = DateTime.Now;

            var i = Int32.MaxValue;
            while (i > 0)
            {
                i--;
            }
            var end = DateTime.Now;

            return Content( end.Subtract(start).ToString() );
        }

    }
}
于 2011-05-24T20:42:01.197 に答える