asp.net core 系列之Response caching(1)

yuan發表於2019-06-24

這篇文章簡單的講解了response caching:

講解了cache-control,及對其中的頭和值的作用,及設定來控制response caching;

簡單的羅列了其他的快取技術:In-memory caching , Distributed Cache , Cache Tag Helper , Distributed Cache Tag Helper ;

講解了使用ResponseCache attribute來控制response caching生成合適的頭

 

Overview

響應快取減少了客戶端或者代理到web伺服器的請求的次數響應快取也可以減少web伺服器的生成響應的執行的工作量。響應快取被頭部控制,頭部指出了你想要客戶端,代理和中介軟體怎樣快取響應。

ResponseCache attribute 參加設定響應快取頭部,which clients may honor when caching responses. (當快取響應時,客戶端會受這些屬性影響)Response Caching Middleware 可以被用來在伺服器上快取響應。 中介軟體可以使用ResponseCacheAttribute屬性來影響服務端快取行為。 

HTTP-based response caching 

HTTP 1.1 Caching specification(規格,詳述,說明書)描述了網路快取應該怎樣表現(Internet caches should behave.) 主要的用於快取的HTTP頭,是Cache-Control, 它被用於指定快取指令。這個指令控制快取行為,當請求從客戶端到服務端的時候,並且當響應從服務端返回客戶端的時候。

公共的Cache-Control 指令在下表中被展示了:

其他快取頭在快取中扮演的角色,羅列在下面了:

注意:Cache-Control,是用在從請求中的HTTP頭,可以用來控制伺服器中快取行為。

HTTP-based caching respects request Cache-Control directives

HTTP 1.1 Caching specification for the Cache-Control header (HTTP 1.1 快取規格對於Cache-Control)要求一個快取遵守一個有效的Cache-Control ,這個Cache-Control頭是被客戶端傳送的。一個客戶端可以傳送一個帶no-cacheheader,並且強制要求伺服器為每個請求生成一個新的響應。

總是遵守客戶端Cache-Control請求頭是有意義的,如果你考慮HTTP快取的目標。在官方的說明書下,

快取意味著減少潛在因素和網路管理,對滿足請求跨客戶端,代理和伺服器網路。它不是一種控制原伺服器上的載入的必須的方式。

當使用Response Caching 中介軟體時,開發者是沒法對快取行為控制的。因為中介軟體附著於官方快取說明書。當決定提供一個快取響應時,對這個中介軟體的計劃豐富(planned enhancements to the middleware)對於達到配置中介軟體來忽視請求的Cache-Control頭的目的,是一個機會(Planned enhancements to middleware are an opportunity to middleware to ignore a request’s Cache-Control header when deciding to serve a cached response.)。計劃的豐富提供了一個機會來更好的控制伺服器載入。

Other caching technology in ASP.NET Core ASP.NET Core上的其他快取技術

  • In-memory caching 記憶體快取

    In-memory caching 使用伺服器記憶體來儲存快取資料。這種型別的快取適合使用sticky sessionsticky:不動的)的一個或者多個伺服器Sticky sessions 意味著從客戶端發出的請求總是路由到同一臺伺服器處理。

    更多資訊:Cache in-memory in ASP.NET Core.

  • Distributed Cache 分散式快取

    使用一個分散式快取來儲存資料在記憶體中,當應用部署在雲上或者伺服器叢集上時。快取是在這些處理請求的伺服器之間共享的。客戶端可以提交一個請求,請求可以被組群裡的任意伺服器處理,如果快取資料對於客戶端是可用的。ASP.NET Core提供了SQL ServerRedis分散式快取

    更多資訊:Distributed caching in ASP.NET Core.

  • Cache Tag Helper

    使用Cache Tagmvc頁面或者Razor Page中快取內容Cache Tag Helper用記憶體快取資料

    更多資訊:Cache Tag Helper in ASP.NET Core MVC

  • Distributed Cache Tag Helper

    在分散式雲或者web叢集場景中使用Distributed Cache Tag Helper 來快取Mvc view或者Razor Page中的內容The Distributed Cache Tag Helper SQL Server或者Redis來快取資料

    更多資訊:Distributed Cache Tag Helper in ASP.NET Core.

ResponseCache attribute

為了在response caching (響應快取)上設定合適的頭,ResponseCacheAttribute 指出了必須的引數。(即,可以通過ResponseCacheAttribute,設定response caching上的頭的值)

注意:對於包含驗證資訊的客戶端內容,不允許快取。對於那些不會基於使用者的身份或者使用者是否登入而改變的內容,才應該允許被快取。

VaryByQueryKeys 隨著給出的query keys的集合的值,改變儲存的響應。When a single value of * is provided, the middleware varies responses by all request query string parameters. 

Response Caching Middleware 必須被允許設定VaryByQueryKeys屬性。否則,一個執行時異常會被丟擲。對於VaryByQueryKeys屬性,並沒有一個對應的HTTP頭部。這個屬性是一個被Response Caching Middleware 處理的HTTP 功能。對於中介軟體提供一個快取的響應,查詢字串和查詢字串值必須匹配之前的請求.(即,如果查詢字串和查詢字串值和之前的一樣時,中介軟體會直接返回一個快取的響應;否則,返回一個新的響應。)例如,考慮下表中的一系列的請求和結果:

第一個請求被伺服器返回,並且快取到中介軟體中。第二個請求是被中介軟體返回,因為查詢字串匹配之前的請求。第三個請求不是在中介軟體快取中的,因為查詢字串值不匹配之前的請求。

ResponseCacheAttribute用於配置和建立一個ResponseCacheFilter.    

ResponseCacheFilter執行的工作,更新合適的HTTP頭和響應的功能(即,ResponseCacheAttribute的功能)The filter:

  • 移除任何存在的Vary, Cache-Control, Pragma頭部
  • 根據設定在ResponseCacheAttribute中的屬性輸出合適的頭部

  • 更新the response caching HTTP feature如果VaryByQueryKeys被設定了

Vary

這個頭部會被寫,當VaryByHeader屬性被設定了。這個屬性(VaryByHeader)設定Vary屬性的值。下面是使用VaryByHeader屬性的例子:

[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Cache1Model : PageModel
{

用這個例子,使用瀏覽器工具觀察response headers(響應頭)。 下面的響應頭隨著Cache1 page response 被髮送了。

Cache-Control: public,max-age=30
Vary: User-Agent
NoStore and Location.None

NoStore重寫了大部分的其他屬性。當這個屬性被設定為true,Cache-Control頭被設定為no-store.

如果Location設定為None:

  • Cache-Control 設定為no-store, no-cache

  • Pragma設定為no-cache.

如果NoStorefalse並且LocationNoneCache-Control ,Pragma被設定為no-cache.

NoStore是典型的被設定為true,為了error pages. 示例中的Cache2 page生成響應頭,指示客戶端不要儲存響應。

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class Cache2Model : PageModel
{

這個示例應用返回Cache2 page 帶有下面的頭:

Cache-Control: no-store,no-cache
Pragma: no-cache
Location and Duration

為了可以快取,Duration必須被設定為一個積極的值並且Location必須是任意的或者Client. 這種情況下Cache-Control頭被設定為location的值,並且跟著一個響應的max-age.

注意:

Location’s options of Any and Client轉化為Cache-Control頭的值分別為publicprivate. 正如之前提到的,設定LocationNone會設定Cache-ControlPramga頭為no-cache:

[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public class Cache3Model : PageModel
{

示例應用返回的Cache3 page 帶有下面的頭:

Cache-Control: public,max-age=10
Cache profiles

取代重複的在很多controller action attributes響應快取設定,cache profiles 可以被設定為options,當在Startup.ConfigureService中設定MVC/Razor Pages. 在引用的cache profiles中發現的值被用作預設值,隨著ResponseCacheAttribute並且被這個attribute上指定的任意properties重寫。(即很多重複的響應快取設定可以在Startup.ConfigureService中設定,再隨著ResponseCacheAttribute設定在action上)

建立一個cache profile. 下面的例子展示了30秒的cache profile,在示例應用的Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.CacheProfiles.Add("Default30",
            new CacheProfile()
            {
                Duration = 30
            });
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

這個示例應用的Cache4 page model 引用了Default30 cache profile:

[ResponseCache(CacheProfileName = "Default30")]
public class Cache4Model : PageModel
{

這個ResponseCacheAttribute可以被用在

  • Razor Page handlers(classes) - 屬性可以被用到處理方法

  • MVC controllers(classes)

  • MVC actions (methods) - Method-level attributes override the settings specified in class level attributes. 方法級別的會覆蓋類級別的

Default30 profile導致的應用於Cache4 page response 的頭是:

Cache-Control: public,max-age=30

 

 參考資料:

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-2.2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章