2016-05-13 51 views
1

我們有一個使用Strathweb.CacheOutput.WebApi2進行高速緩存的Web API 2應用程序。檢測Web API請求是否由高速緩存提供

簡短問題:有沒有一種方法可以檢測Application_LogRequest(或任何地方,真的)請求是否由緩存提供服務?

長問題: 最近,我們一直在關注性能,看看我們可以改進哪些API調用。我從我們的日誌(包括持續時間)中提取了一個清單,以查看最糟糕的違規者。對於最壞的違規者,我的意思是最長的平均工期和/或最多的電話。

但是這些數字具有誤導性,因爲緩存的請求包含在統計信息中。緩存的請求通常在半秒或更短的時間內提供,因此它們將平均持續時間縮短。另外,如果正在進行一個特定的呼叫,例如每分鐘1000次,但其中有999個被緩存,我並不在乎。

因此,我想在我的日誌中添加一個標誌,指示請求是否由緩存提供服務,因此我可以排除這些請求。我們所有的日誌都是在Application_LogRequest事件中完成的。但即使我可以在其他地方檢測到,我也可以在HttpContext.Current.Items中存儲一個值,以便稍後檢索。

回答

1

Strathweb CacheOutputAttribute不會在http響應或其他地方添加一些可靠的信息,以便知道響應是否從緩存提供。

你可以從中得到它,然後用你自己的方法替換你所有的用法CacheOutputAttribute

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class YourCustomizedCacheOutputAttribute : CacheOutputAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
     // If response is set, it has been retrieved from cache. 
     actionContext.Request.Properties["yourCacheHitKey"] = 
      actionContext.Response != null; 
    } 
} 

當然,使用的東西比其他HttpRequestMessage.Properties如果在那裏你登錄你沒有訪問它。

您可以通過例如響應加入一些自定義標題,如果泄露了這一點,以瀏覽器是不是你的問題:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class YourCustomizedCacheOutputAttribute : CacheOutputAttribute 
{ 
    // "X-" prefix is deprecated, but the rational behind this is about wannabe 
    // standard header. I do not intend this one to become standard for anything. 
    private const string _cacheHeader = "X-Cache"; 
    protected override void ApplyCacheHeaders(HttpResponseMessage response, 
     CacheTime cacheTime) 
    { 
     base.ApplyCacheHeaders(response, cacheTime); 

     if (response.Headers.Contains(_cacheHeader)) 
      return; 

     // At this point, we do not know. miss by default. 
     response.Headers.Add(_cacheHeader, "miss"); 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     base.OnActionExecuting(actionContext); 
     if (actionContext.Response == null) 
      return; 

     // Response has been retrieved from cache. 
     // Headers.Remove does not fail if not already there. 
     response.Headers.Remove(_cacheHeader); 
     actionContext.Response.Headers.Add(_cacheHeader, "hit"); 
    } 
} 
+0

謝謝!我希望有一種方法不需要重寫任何東西,但它看起來不可能。感謝您的示例代碼。這一定會有所幫助! –