ASP.NET Core中的内存缓存

ASP.NET Core中的内存中缓存

让我们看看如何通过缓存优化ASP.NET Core应用程序性能

我相信,在我们的工作中,每个人都收到来自客户的请求或来自我们应用程序用户的反馈,以提高响应速度。

如果在编写代码时仅使用最佳实践还不够,那么我们肯定需要使用缓存来微调我们的应用程序。

缓存包括将那些不经常更改的信息存储在某个地方。高频访问是我们应用程序的业务要求。

在本文中,我们将看到ASP.NET Core可用于缓存的内容。

IMemoryCache和IDistributedCache

这两个接口代表.NET Core中用于缓存的内置机制。您可能已经听说过的所有其他技术都是这两个接口的实现。在本文中,我们将详细介绍内存缓存,而在以后的文章中将研究分布式缓存。

在ASP.NET Core中启用内存中缓存

我们可以使用ConfigureServices方法将ASP.NET内存中缓存合并到应用程序中。您可以在Startup类中启用MemoryCache,如下面的代码片段所示。

public void ConfigureServices(IServiceCollection services)
{services.AddMvc();services.AddMemoryCache();
}

AddMemoryCache方法允许我们注册IMemoryCache接口,如上面提到的,将被用于高速缓存的基础。下面我们看到框架中接口的定义:

public interface IMemoryCache : IDisposable
{bool TryGetValue(object key, out object value);ICacheEntry CreateEntry(object key);void Remove(object key);
}

接口中提供的方法并不是唯一可用于缓存的方法:我们将在后面看到,存在各种扩展来丰富可用的API并极大地促进其使用。例如:

public static class CacheExtensions
{public static TItem Get<titem>(this IMemoryCache cache, object key);public static TItem Set<titem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options);public static bool TryGetValue<titem>(this IMemoryCache cache, object key, out TItem value);...
}

注册后,该接口可以注入到我们要使用它的类构造函数中,如下所示:

private IMemoryCache cache;
public MyCacheController(IMemoryCache cache){this.cache = cache;}

在下面的部分中,我们将研究如何在ASP.NET Core中使用缓存API来存储和检索对象。

使用IMemoryCache存储和检索项目

要使用IMemoryCache接口写入对象,请使用Set ()方法,如以下代码片段所示。

[HttpGet]
public string Get()
{cache.Set(“MyKey”, DateTime.Now.ToString());return “This is a test method...”;
}

此方法接受两个参数,第一个是键,用于标识缓存的对象,第二个参数是我们要存储的值。要从缓存中检索对象,请使用Get ()方法,如下面的代码片段所示。

[HttpGet(“{key}”)]
public string Get(string key)
{return cache.Get<string>(key);
}

如果我们不确定缓存中是否存在特定的密钥,则可以使用TryGetValue()方法进行帮助:它返回一个布尔值,指示所请求的密钥存在或不存在。

下面是如何使用TryGetValue修改Get()方法的方法。

[HttpGet(“{key}”)]
public string Get(string key)
{string obj;if (!cache.TryGetValue<string>(key, out obj))obj = DateTime.Now.ToString();cache.Set<string>(key, obj);return obj;
}

可用的另一种方法是GetOrCreate()方法,该方法验证所需密钥的存在,否则,该方法将为您创建它。

[HttpGet(“{key}”)]
public string Get(string key)
{return cache.GetOrCreate<string>(“key”,cacheEntry => {return DateTime.Now.ToString();});
}

如何在ASP.NET Core中的缓存数据上设置过期策略

当我们使用IMemoryCache存储对象时,MemoryCacheEntryOptions类为我们提供了各种技术来管理缓存数据的到期时间。

我们可以指定一个固定的时间,在该时间之后某个特定的密钥将过期(绝对过期),或者如果在某个特定的时间(滑动过期)之后没有访问它,则它可以过期。此外,还可以使用Expiration Token在缓存的对象之间创建依赖关系。这里有一些例子

//absolute expiration using TimeSpan
_cache.Set("key", item, TimeSpan.FromDays(1));//absolute expiration using DateTime
_cache.Set("key", item, new DateTime(2020, 1, 1));//sliding expiration (evict if not accessed for 7 days)
_cache.Set("key", item, new MemoryCacheEntryOptions
{SlidingExpiration = TimeSpan.FromDays(7)
});//use both absolute and sliding expiration
_cache.Set("key", item, new MemoryCacheEntryOptions
{AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(30),SlidingExpiration = TimeSpan.FromDays(7)
})// This method adds a trigger to refresh the data from background
private void UpdateReset()
{var mo = new MemoryCacheEntryOptions();mo.RegisterPostEvictionCallback(RefreshAllPlacessCache_PostEvictionCallback);mo.AddExpirationToken(new CancellationChangeToken(new CancellationTokenSource(TimeSpan.FromMinutes(35)).Token));Cache.Set(CACHE_KEY_PLACES_RESET, DateTime.Now, mo);
}// Method triggered by the cancellation token that triggers the PostEvictionCallBack
private async void RefreshAllPlacesCache_PostEvictionCallback(object key, object value, EvictionReason reason, object state)
{// Regenerate a set of updated datavar places = await GetLongGeneratingData();Cache.Set(CACHE_KEY_PLACES, places, TimeSpan.FromMinutes(40));// Re-set the cache to be reloaded in 35minUpdateReset();
}

缓存回调

MemoryCacheEntryOptions类提供的另一个有趣功能是允许我们注册回调的功能,当从缓存中删除一项时将执行该回调。

MemoryCacheEntryOptions cacheOption = new MemoryCacheEntryOptions()  
{  AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now),  
};  
cacheOption.RegisterPostEvictionCallback(  (key, value, reason, substate) =>  {  Console.Write("Cache expired!");  }); 

缓存标签助手

到目前为止,我们已经看到.NET Core提供的API的使用,从而能够直接使用IMemoryCache接口手动在缓存中写入和读取项目。此接口还有其他实现,可能非常有用。例如,在Web环境中,如果我们使用.NET Core MVC框架,则可以使用helper cache tag存储部分页面。它非常简单易用:您可以将视图的一部分包装在缓存标签中以启用缓存:

<cache>
<p>Ora: @DateTime.Now</p>
</cache>

对于页面的每个后续请求(包含此标记),将从缓存中使用该段的正文。如果将其放在页面上并观察其输出,则可以轻松检查行为。当然,我们使用它的方式仅出于示例目的,但是当您尝试渲染需要大量资源的页面时,您可以欣赏它的功能。一个明显的缓存候选是视图组件[1]调用

<cache expires-on="@TimeSpan.FromSeconds(600)">
@await Component.InvokeAsync("BlogPosts", new { tag = "popular" })
</cache>

在上一个代码段中,您还可以通过属性expires-on来了解如何管理缓存中对象的过期期限。还有其他两种选择:

•过期时间:将使用TimeSpan进行评估以指示一段时间,此后必须重新生成内容;•过期滑动:还应使用指示闲置时间的TimeSpan。每次从缓存中读取内容时,都会将其删除延迟。

另一个可定制方面涉及配置缓存标准的可能性。我们可能需要根据一些变量来更新缓存的对象。一些要求是由覆盖变化经过下列属性:

•按路由变化:通过路由参数的名称(例如id)进行了增强,以指示在指示的属性更改时必须重新生成内容;•因查询而异:当更改查询字符串键时,将生成并缓存内容;•按用户不同:当我们显示已登录用户的特定数据时(例如,包含名称和照片的个人资料框),必须将其设置为true;•按标题变化:如果我们使用HTTP请求标头显示语言内容,则根据HTTP请求标头来更改缓存,例如“ Accept-Language”。•cookie-variable-by-cookie:允许您根据cookie的内容更改缓存,我们必须指出其名称。

可以使用一个或多个按属性的属性来执行高级缓存策略,但是,有句著名的名言:“功能强大,责任重大”。

结论

使用内存缓存可以使您将数据存储在服务器的内存中,并通过删除对外部数据源的不必要请求来帮助我们提高应用程序性能。如我们所见,它非常易于使用。

我提醒您,当您的应用程序托管在多台服务器或云托管环境中时,不能使用这种方法。在下一篇文章中,我们将讨论分布式缓存。

下次见!

References

[1] 组件: https://www.blexin.com/en-US/Article/Blog/Kestrel-build-me-up-31

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Spring5]IOC容器_Bean管理注解方式_完全注解开发

完全注解开发 &#xff08;1&#xff09;创建配置类&#xff0c;替代xml配置文件 package com.atguigu.spring.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;Configuration //作为配置…

ASP.NET Core在 .NET 5 Preview 7的更新

.NET 5 Preview 7现在可以用了&#xff0c;可以进行评估了。这是此版本中的新增功能&#xff1a;Blazor WebAssembly应用程序现在针对.NET 5更新了Blazor WebAssembly的调试要求Blazor的可访问性改进Blazor的性能改进证书认证性能改进发送HTTP/2 PING帧支持Kestrel套接字传输中…

[Spring5]AOP底层原理

AOP底层原理 1.AOP底层使用动态代理 &#xff08;1&#xff09;有两种情况动态代理 第一种 有接口的情况&#xff0c;使用JDK动态代理 a.创建接口实现类代理对象&#xff0c;增强类的方法 第二种 没有接口的情况&#xff0c;使用CGLIB动态代理 a.创建子类的代理对象&#…

Hangfire定时触发作业,好像很简单?

【导读】本节我们继续稍微详细讲讲在我没有详细了解源码的前提下来探讨通过Hangfire定时触发作业有哪些需要注意的事项间隔时间内执行作业举个栗子&#xff0c;每隔10秒监控系统CPU&#xff0c;若CPU飙高&#xff08;根据实际业务定义百分比&#xff09;则在控制台打印输出&…

[Swagger2]Swagger简介

Swagger简介 前后端分离 前端 -> 前端控制层、视图层 后端 -> 后端控制层、服务层、数据访问层 前后端通过API进行交互 前后端相对独立且松耦合 产生的问题 前后端集成&#xff0c;前端或者后端无法做到“及时协商&#xff0c;尽早解决”&#xff0c;最终导致问题…

五分钟快速搭建Serverless免费邮件服务

1. 引言本文将带你快速基于 Azure Function 和 SendGrid 构建一个免费的Serverless&#xff08;无服务器&#xff09;的邮件发送服务&#xff0c;让你感受下Serverless的强大之处。该服务可以每月免费发送2,5000封&#xff0c;这是完全白嫖啊&#xff0c;感兴趣的&#xff0c;赶…

[Swagger2]SpringBoot集成Swagger

SpringBoot集成Swagger 引入依赖 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</…

IdentityServer4 4.x版本 配置Scope的正确姿势

点击上方蓝字"小黑在哪里"关注我吧前言IdentityServer4 是为ASP.NET Core系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证的框架IdentityServer4官方文档&#xff1a;https://identityserver4.readthedocs.io/看这篇文章前默认你对IdentityServer4 已经有一…

[Swagger2]配置Swagger

配置Swaggr 1、Swagger实例Bean是Docket&#xff0c;所以通过配置Docket实例来配置Swaggger。 package com.xxxx.swagger2.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.doc…

.Net Core微服务入门全纪录(完结)——Ocelot与Swagger

点击上方蓝字"小黑在哪里"关注我吧前言上一篇【.Net Core微服务入门全纪录&#xff08;八&#xff09;——Docker Compose与容器网络】完成了docker-compose.yml文件的编写&#xff0c;最后使用docker compose的一个up指令即可在docker中运行整个复杂的环境。本篇简单…

[Swagger2]Swaggr配置扫描接口配置Swagger开关

Swagger配置扫描接口 1、构建Docket时通过select()方法配置怎么扫描接口。 Bean public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()// 通过.select()方法&#xff0c;去配置扫描接口,RequestHandlerSelectors配置如何扫描…

最全.Net学习资料库上线,今日可免费下载各类资源!(附百度云链接)

送资料送资料1 适合学习者&#xff1a;0-10年.Net开发人员2 更新时间&#xff1a;2020年7月24日3 在哪领取&#xff1a;文末扫码免费领取4 包含课程&#xff1a;零基础就业必修/高级开发必修/架构师必修5 配套资料&#xff1a;视频配套源码/最新面试题合集/最新技术书/安装包你…

[Swagger2]拓展:其他皮肤

拓展&#xff1a;其他皮肤 我们可以导入不同的包实现不同的皮肤定义&#xff1a; 1、默认的 访问 http://localhost:8080/swagger-ui.html <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><ve…

如何基于 DDD 构建微服务?

本文将讨论微服务与 DDD 涉及到的概念、策划和设计方法&#xff0c;并且尝试将一个单体应用拆分成多个基于 DDD 的微服务。微服务的定义微服务中的“微”虽然表示服务的规模&#xff0c;但它并不是使应用程序成为微服务的唯一标准。当团队转向基于微服务的架构时&#xff0c;他…

.NET Core ResponseCache【缓存篇(一)】

一、前言源码1、最近一直在看项目性能优化方式&#xff0c;俗话说的好项目优化第一步那当然是添加缓存&#xff0c;我们的项目之所以卡的和鬼一样&#xff0c;要么就是你的代码循环查询数据库&#xff08;这个之前在我们的项目中经常出现&#xff0c;现在慢慢在修正&#xff09…

[Swagger2]分组和接口注释及小结

分组和接口注释及小结 配置API分组 1、如果没有配置分组&#xff0c;默认是default。通过groupName()方法即可配置分组&#xff1a; Bean public Docket docket(Environment environment) {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(&qu…

Asp.Net Core 中的“虚拟目录”

写在前面现在部署Asp.Net Core应用已经不再限制于Windows的IIS上&#xff0c;更多的是Docker容器、各种反向代理来部署。也有少部分用IIS部署的&#xff0c;IIS部署确实是又快又简单&#xff0c;图形化操作三下五除二就可以发布好一个系统了。在过去Asp.Net MVC 项目部署的时候…

[mybatis]缓存_缓存有关的设置以及属性

缓存有关的设置以及属性 全局配置中的设置 和缓存有关的设置/属性1.cacheEnabletrue&#xff1b;false&#xff1b;关闭缓存(二级缓存关闭)(一级缓存一直可用的)2.每个select标签都有useCache“true”&#xff1b; false&#xff1b;不使用缓存(一级缓存依然使用&#xff0c;二…

EF批量插入太慢?那是你的姿势不对

大概所有的程序员应该都接触过批量插入的场景&#xff0c;我也相信任何的程序员都能写出可正常运行的批量插入的代码。但怎样实现一个高效、快速插入的批量插入功能呢&#xff1f;由于每个人的工作履历&#xff0c;工作年限的不同&#xff0c;在实现这样的一个需求时&#xff0…

[RabbitMQ]什么是MQ

什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;MQ 是一种非常…