ASP.Net Core 2.0 - ResponseCaching 中間件 - 不在伺服器上記憶體
我想在 asp.net core 2.0 中使用伺服器端響應記憶體(輸出記憶體),發現了響應記憶體中間件,並想嘗試一個全新的 asp.core mvc 項目。
這是上面連結中的描述,這讓我認為這可以像輸出記憶體一樣使用。
中間件確定響應何時可記憶體、儲存響應並提供來自記憶體的響應。
這是我的 startup.cs 的樣子。
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddResponseCaching(); services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseResponseCaching(); if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } }這是 HomeController.cs
[ResponseCache(Duration = 60)] public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } public IActionResult Contact() { ViewData["Message"] = "Your contact page."; return View(); } public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } }_Layout.cshtml 文件的底部還有一個時間戳,所以我可以知道頁面何時呈現,如下所示。
<p>© 2018 - ResponseCachingMiddleware - @DateTime.UtcNow</p>Cache-Control 標頭似乎很好,這是我在載入頁面時在標頭中得到的,但時間戳會在每秒每次刷新時不斷更新。
Cache-Control:public,max-age=60我從 MS 文件中了解到的是響應記憶體中間件是負責記憶體響應的伺服器端記憶體機制,而響應記憶體似乎只是一個過濾器來操作記憶體的響應標頭。
無法判斷我的理解或程式碼是否有問題,我想抱怨自從我開始使用 ASP.Net Core 進行原型設計以來,我經常有這種感覺。也許您還可以建議更好的資源作為附帶主題。
我在 ASP.NET Core 2.0 之前查看過這篇文章 - Http Response Caching Middleware - Nothing cached
也檢查了這一點,但似乎唯一的區別是我使用的是 mvc。 https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs
謝謝
編輯:我在輸出視窗中看到下面的消息,除了我已經檢查過響應記憶體中間件的幾個地方之外,在Google上找不到任何關於它的資訊。
Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware:資訊:無法記憶體此請求的響應。
注意:我希望我可以創建#response-caching-middleware 標籤。不確定#responsecache 是否相關。
我最近也有同樣的困惑。
ASP.Net Core 的 ResponseCaching 確實提供了客戶端記憶體(通過 HTTP 響應標頭)和伺服器端(通過記憶體記憶體的中間件,如果響應在記憶體中,該中間件會短路其他中間件)。伺服器端部分讀取 HTTP 響應記憶體標頭以確定它是否應該進行伺服器端記憶體(類似於 ISP 或 CDN 可能會做的事情)。
不幸的是,調試伺服器端 ResponseCaching 很棘手,因為它有奇怪的規則並且沒有足夠的日誌記錄。就我而言,我下載了 Microsoft 的原始碼以單步執行它並找到我的程式碼的問題。
您在輸出視窗“無法記憶體此請求的響應”中找到的註釋是一條線索。
請求的伺服器端記憶體有 2 個部分。伺服器必須在第一次請求 url 時填充記憶體。它將在第二次請求時提供記憶體版本。請注意錯誤消息何時出現,如果它是在第一個或第二個請求上。這將告訴您它是否無法儲存在記憶體中,或者是否無法從記憶體中檢索。
儲存和檢索的規則都在這個原始碼文件中: https ://github.com/aspnet/ResponseCaching/blob/3bf5f6a1ce69b65c998d6f5c739822a9bed4a67e/src/Microsoft.AspNetCore.ResponseCaching/Internal/ResponseCachingPolicyProvider.cs
您的“Cache-Control:public,max-age=60”標頭應該符合這些規則就好了。
我的猜測是你實際上讓它工作,但不知道如何正確測試它。本期中提到的 ResponseCaching 有一個違反直覺的部分:https ://github.com/aspnet/Home/issues/2607 本質上,如果瀏覽器發送 no-cache 或 no-store 標頭(當您點擊 CTRL+ F5 或打開調試器工具),ASP.Net Core 的 ResponseCaching 將接受瀏覽器的請求並重新生成響應。
因此,為了測試您的程式碼是否正常工作,您可能載入了已啟動記憶體的頁面,然後您按 CTRL+F5 強制刷新您的瀏覽器,並且您希望伺服器端響應記憶體條目而不是執行您的 WebAPI程式碼。但是,它尊重無記憶體請求標頭並繞過記憶體(並在輸出日誌中寫入該消息)。
對此進行測試的方法是清除請求之間的瀏覽器記憶體(或切換到隱身模式),而不是使用 CTRL+F5。
附帶說明一下,尊重 no-cache/no-store 請求標頭可能是一個糟糕的設計選擇,因為 ASP.Net Core 的 ResponseCache 很可能由擁有響應的伺服器使用,而不是像 CDN 這樣的中間記憶體/網際網路服務提供商。我已經擴展了基本的 ResponseCache 選項,以禁用尊重這些標頭(以及將記憶體序列化到磁碟,而不是僅在記憶體中)。它是預設記憶體的簡單替代品。
你可以在這裡找到我的擴展: https ://github.com/speige/AspNetCore.ResponseCaching.Extensions https://www.nuget.org/packages/AspNetCore.ResponseCaching.Extensions
還有一些其他的 ResponseCaching 問題需要注意,您可能已經在您發布的部落格 URL 中閱讀過這些問題。使用 set-cookie 驗證的請求和響應不會被記憶體。只有使用 GET 或 HEAD 方法的請求才會被記憶體。如果 QueryString 不同,它將創建一個新的記憶體條目。此外,如果請求的某些條件與先前記憶體的請求不同(例如:使用者代理、接受編碼等),通常您需要一個“Vary”標頭來防止記憶體。最後,如果一個中間件處理一個請求,它會短路後面的中間件。確保您的 app.UseResponseCaching() 在 app.UseMVC() 之前註冊
我遇到了同樣的問題,我正要大發雷霆,我已經設置
app.UseResponseCaching();好了services.AddResponseCaching();並添加ResponseCache了我的操作,就像微軟官方文件中所說的一樣,儘管cache-controll標題在響應返回時設置正確來自伺服器,但在伺服器端仍然沒有記憶體。在這個問題上花費了幾個小時後,我弄清楚了問題出在哪里以及為什麼沒有記憶體在伺服器上。
瀏覽器預設為請求設置
cache-controll值max-age=0(如果請求不是由後退或轉發引起的),即使您通過在操作(或控制器)頂部cache-controller添加屬性在響應中正確設置,因為請求發送的設置為,伺服器無法記憶體響應,我認為這也必須添加到響應記憶體限制列表中ResponseCache``cache-controller``max-age=0無論如何,您可以通過在呼叫之前添加幾行程式碼來覆蓋瀏覽器預設行為,
app.UseResponseCaching();另一方面,您需要在呼叫之前添加自定義中間件來修改請求cache-control標頭值app.UseResponseCaching();。請參閱下面的程式碼,對我有用,希望對你也有用
app.Use(async (ctx, next) => { ctx.Request.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromSeconds(60) }; await next(); } ); app.UseResponseCaching();為了確保 ResponseCaching 按預期工作,您也可以使用郵遞員,但您必須在設置中將**“發送無記憶體標頭”設置為關閉**,請參見下圖
