ASP.NET Core 1.0 中的响应缓存和内存缓存






4.33/5 (2投票s)
ASP.NET Core 1.0 中的响应缓存和内存缓存
引言
ASP.NET 5 支持几种缓存机制来提高应用程序的性能和响应速度。以下是在不同级别实现缓存的几种选项。
- 响应缓存
- 内存缓存
- SQL Server 中的分布式缓存或内存缓存服务器
目前,ASP.NET 5 不支持输出缓存,但将在未来版本中添加。本文将探讨响应缓存和内存缓存。
响应缓存
如果我们使用 `ResponseCache` 属性修饰 Action、Controller 或全局级别,响应缓存会在应用程序的响应中添加与缓存相关的标头。与早期版本的 ASP.NET 中的输出缓存不同,`ResponseCache` 不会在服务器上存储 HTTP 响应。它只是在响应中添加 "Cache-Control" 标头,现在由客户端选择是否在浏览器或任何中间服务器中缓存响应。如果浏览器或缓存服务器缓存了之前的响应,它可以减少服务器往返次数。在此示例中,我们使用 "ResponseCache
" 属性修饰了 `ResponseCache` Action,该属性接受 `Duration` 参数。
[ResponseCache(Duration =60)] public ActionResult ResponseCache() { return View("Index"); }
在响应中,我们看到 Cache-Control 标头已添加到 HTTP 响应中
Cache-Control 标头的值可以是 Public、Private 或 no-cache。让我们逐一讨论。
Public
表示响应允许任何缓存机制进行缓存。大多数情况下,如果页面与用户无关,我们可以使其公开可缓存。
Private
Cache-Control 标头的值为 "private",这意味着任何中间缓存服务器都不会缓存它。我们可以将 "Location = ResponseCacheLocation.Client
" 与 ResponseCache
一起指定,使其成为私有的。
[ResponseCache(Duration =60 , Location = ResponseCacheLocation.Client)] public ActionResult ResponseCache() { return View("Index"); }
在响应中,我们看到 "Cache-Control" 标头的值为 private。因此,响应仅允许在用户的私有区域(如浏览器)中进行缓存。
无缓存
如果我们不想将响应缓存到任何缓存层,可以将 `Location` 值指定为 none。以下是示例代码。
[ResponseCache(Duration =60 , Location = ResponseCacheLocation.None)] public ActionResult ResponseCache() { return View("Index"); }
用于缓存的附加 HTTP 标头包括 "Pragma" 和 "Vary",下面将进行说明。从规范中了解更多关于 HTTP 缓存的信息。
ResponseCache 属性
ResponseCache
属性支持许多参数,本节将逐一介绍。
Duration: 类型 int
响应应缓存的最大时间(以秒为单位)。除非 `NoStore` 为 true,否则此项是必需的。
Location: 类型 ResponseCacheLocation
响应可以缓存的位置。可以是 Any、None 或 Client。默认值为 Any。根据此值,"Response-Cache" 标头的值会发生变化。
NoStore : 类型 bool
确定是否应存储值,并覆盖其他属性值。当为 true 时,Duration 被忽略,Location(除 None 外)也被忽略。No Store 的常见场景可能是显示错误页面。错误页面通常是用户特定的,我们不希望将一个用户生成的错误页面显示给另一个用户。
VaryByHeader : 类型 string
设置时,响应中会写入 vary 响应标头。当标头的值发生变化时,缓存的版本将失效。
CacheProfileName : 类型 string
设置时,确定要使用的缓存配置文件的名称。我们可以在 ASP.NET 5 应用程序的 Configuration 部分指定缓存配置文件。
Order int
过滤器的顺序(来自 IOrderedFilter
)。
缓存配置文件
我们可以在应用程序级别维护缓存配置文件,并在 Action 或 Controller 级别使用。该机制将减少代码重复。在此示例中,我们创建了一个名为 "private cache" 的缓存配置文件。
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.CacheProfiles.Add("PrivateCache", new CacheProfile() { Duration = 60, Location = ResponseCacheLocation.None }); }); services.AddCaching(); }
现在,我们可以在 Controller/Action 级别使用该配置文件。以下是实现此功能的示例代码。
[ResponseCache(CacheProfileName = "PrivateCache")] public ActionResult ResponseCache() { return View("Index"); }
内存缓存
内存缓存使用分配给进程的内存来存储信息。它不是分布式的,也不是可伸缩的,因为缓存数据存储在服务器进程中。要配置内存缓存,我们需要在 project.json 文件中添加以下包。
"Microsoft.Extensions.Caching.Memory": "1.0.0-rc1-final", "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc1-final"
ASP.NET Core 中的缓存是一项服务,应通过依赖注入从应用程序中引用。要在应用程序中注册缓存服务并使其可用,请在 Startup.cs 文件的 ConfigureServices
方法中添加以下行。以下是示例代码。
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddCaching(); }
获取和设置内存缓存的值
在此示例中,我们将学习如何获取和设置内存缓存的值。要获取值,我们可以使用 `Get` 或 `TryGateValue()` 函数。要设置值,我们可以使用 `Set()` 函数。以下是完整的内存缓存代码示例。
public class HomeController : Controller { private IMemoryCache cache; private static int data; public HomeController(IMemoryCache cache) { this.cache = cache; } public ActionResult Index() { var Time = DateTime.Now.ToLocalTime().ToString() ; this.cache.Set("Time", Time, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now ) }); ViewBag.Time = Time; return View(); } public IActionResult GetCache() { string Time = null; if (this.cache.TryGetValue("Time", out Time)) { ViewBag.Time = Time; } else ViewBag.Time = DateTime.Now.ToLocalTime().ToString(); return View("Index"); }
Index
Action 会将当前日期时间缓存起来,当我们调用 GetCache()
函数时,它首先检查缓存。 如果缓存存在,则从缓存返回;否则,将返回新的日期时间。缓存的持续时间为一分钟,因为在缓存设置时我们已指定了值。
this.cache.Set("Time", Time, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now ) });
在 AbsoluteExpirationRelativeToNow
属性中。下面显示了设置过期值的另一种方法。
_this.cache.Set("key", "Value", new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromMinutes(1)));
设置缓存优先级
默认情况下,MemoryCache
实例会根据应用程序内存压力自动管理存储的项目,在必要时删除条目。您可以通过在将项目添加到缓存时设置其 CacheItemPriority
来影响缓存条目的管理方式。例如,如果您有一个想要保留在缓存中直到显式删除的项目,您可以使用 NeverRemove
优先级选项。
new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove))
如果您想显式删除缓存条目,可以像这样调用 `remove()` 函数。cache.Remove("Key");
结论
响应缓存允许客户端在各种缓存级别缓存响应,而内存缓存允许在进程内存中进行缓存。但是,它们本质上不是分布式的,也不是可伸缩的。ASP.NET 5 还支持分布式缓存,我们可以将缓存数据存储在 SQL 或 Redis 集群中。