前言

如今缓存成为了优化网站性能的首要利器,缓存使用的好,不仅能让网站性能提升,让用户体验变好,而且还能节约成本(增加一台缓存服务器可能就节约好几台机器);那平时小伙伴们都使用哪些缓存方式呢?这里就来和小伙伴们一起来回顾一下。

正文

缓存的作用其实很明确,如下两方面:

  • 提升数据的获取速度

    通常用在获取数据速度要求比较高的场景,比如一些和设备通信的软件,对时间的要求比较高,如果每次都从数据库读数据会导致消耗多余的时间。

  • 减轻后台应用或数据库服务器的负载

    对于高并发场景的系统,如果每次请求都打到数据库,数据库服务器负载会变大,到达一定瓶颈之后可能让系统体验变差或不可用。

1. 浏览器缓存

1.1 简述

通过控制响应头信息,告诉浏览器让其将对应的数据缓存到本地,在指定时间范围内,可直接从本地缓存中取即可,但浏览器方可以不选择走缓存。

1.2 案例演示

本文中还是使用WebAPI项目进行演示,只是通过不同的API来区分不同案例。

创建好项目中,在默认的WeatherForecastController中添加一个Action方法,如下:

这个时候还没有做缓存处理,所以只要访问都会调用接口获取最新的数据。

在接口方法上只需添加ResponseCache特性就可以实现浏览器缓存,如下:

这样就可以实现客户端缓存了,可能会有小伙伴会点击浏览器的刷新和F5进行测试,这个时候并没有看到缓存效果,其实这个时候浏览器是以新的请求发出的,并不会去缓存里取,但其实请求获取到的数据已经存缓存了。

那怎么去测试呢?每次都 打开多个浏览器标签或用Swagger的形式,如下:

第一次访问:

每次都打开新标签,再访问接口:

除了根据数据没变来判定是缓存数据外,还可以通过请求确定是否从本地缓存中取数据,如下:

Swagger演示,关于如何集成Swagger,之前有专门分享过(跟我一起学.NetCore之Swagger让前后端不再烦恼及界面自定义):

浏览器缓存的原理其实就是在响应头中增加Cache-Control(ResponseCache的方式是通过Action过滤器的形式设置的响应头),告诉浏览器进行数据缓存,在指定时间范围内可以从缓存中取,我们也可以自己手动设置响应头信息来达到同样的效果,如下:

尽管数据已经缓存,浏览器也可以选择不从缓存取,如下:

2. 服务器缓存

2.1 简述

浏览器缓存只是将数据保存在单台电脑的不同位置,如果打开不同的浏览器或不同的电脑访问时,还是起不到缓存的效果,所以搞个服务器缓存肯定是个不错的选择。

将数据缓存到站点服务器中,当请求过来时,如果命中缓存,直接获取返回即可,不调用对应的后台API

2.2 案例

其实这只是在原来浏览器缓存的基础上增加了一个中间件的处理,如下:

代码如下:

运行效果:

由于不同的浏览器保存的数据位置不一样,如果仅仅是本地缓存,那么两个浏览器的数据会返回不一样;另外第一个浏览器访问之后,其他浏览器在时间范围内获得结果是一样的,也不会调用后台接口。

这种服务器端的缓存在有些情况是不生效的,如:请求Method不是Get或Head的不缓存,返回状态码不是200的不缓存,请求头包含Authorization的不缓存等,所以基本很少用这种方式进行缓存操作。

3. 应用内存缓存

3.1 简述

对于上面说到的浏览器缓存和服务器缓存,如果是友好的用户访问,没问题,能起到一定的效果;但如果有人要使坏,不设置对应的请求头访问API(禁用缓存),最终还是会给应用服务器和数据库服务器带来压力。所以需要一种能主动控制的缓存方式,后端程序就是下手的对象,在后端程序中写缓存逻辑,这样缓存策略就由我们自己控制了。

虽然每次请求都会进入应用程序,但会先从缓存中进行获取数据,如果命中缓存,就不再进行数据库访问,直接将缓存数据返回。

3.2 案例

其实框架中针对内存缓存这块已经做好了封装,只需注册相关的服务就可以用了,如下:

注册完成之后,只需要注入就可以使用了,这里增加一个Action方法进行演示:

效果就不截图了,在20秒内,单程序部署情况下,不管怎么访问都会是一样的结果。如果想更多了解MemoryCache的使用,可以看看这篇文章《因MemoryCache闹了个笑话》。

4. 分布式缓存

4.1 简述

内存缓存虽然能解决浏览器和服务器缓存的缺点,但只对单体部署程序比较适用,对于需要分布式部署的程序来说,程序内存之间的缓存数据不能共享,缓存的效果肯定就没那么尽人意,所以分布式缓存就出来了,采用对应的中间件,如Memcache、Redis等,而Redis成为了缓存的首选。

请求的逻辑和内存缓存差不多一样,只是分布式缓存会采用第三方中间件进行数据存储,保证分布式部署的程序共用一套缓存。

4.2 案例

这里还是用最火的Redis做演示,所以需要提前安装Redis,关于Redis系列的文章,小伙伴们可以看这《给我一起学Redis》。

框架也提供了统一操作分布式缓存的接口IDistributedCache,用法和上面的内存缓存基本一样。

这里用的是Redis,所以需要安装对应的Nuget包Microsoft.Extensions.Caching.StackExchangeRed,然后注册相关服务就可以用了,如下:

注册完成之后,只需要注入就可以使用了,这里也增加一个Action方法进行演示:

访问对应的接口,在设置的时间范围内从Redis中读取到的数据一致,过期之后就会清空,程序又会设置新的值,如下:

关于缓存的几种用法就先暂时说这么多,也有小伙伴根据业务场景自己实现的。

实例的源码:https://gitee.com/CodeZoe/dot-net-core-study-demo/tree/main/CacheDemo

总结

缓存之所以现在这么火,其主要目的还是提升数据访问效率,缓解应用和数据库的压力,但同时也会带来一些问题,比如缓存穿透、缓存击穿、缓存雪崩及缓存数据与数据库不一致等问题,后续我们会逐个说说,关注“Code综艺圈”,和我一起学习吧。

使用缓存(Cache)的几种方式,回顾一下~~~的更多相关文章

  1. $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    $.ajax()方法详解   jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...

  2. 对比keep-alive路由缓存设置的2种方式

    方式有两种 .路由元信息(2.1.0版本之前) .属性方式(2.1.0版本之后新增) Vue2.1.0之前: 想实现类似的操作,你可以: 配置一下路由元信息 创建两个keep-alive标签 使用v- ...

  3. 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    很多小伙伴没接触过Redis,以至于去学习的时候感觉云里雾里的,就有一种:教程随你出,懂了算我输的感觉. 每次听圈内人在谈论的时候总是插不上话,小编就偷偷去了解了一下,也算是初入门径. 然后就整理了一 ...

  4. 【修改缓存路径】修改Gradle缓存路径的几种方式

    起因 Android Studio的gradle在缓存处理上有时候会莫名其妙的出问题,必要时需要手动删除缓存,然后重新编译.有时也有出于其他考虑指定gradle缓存路径. 方法1:修改gradle文件 ...

  5. .net core 2.x - 缓存的四种方式

    其实这些微软docs都有现成的,但是现在的人想对浮躁些,去看的不会太多,所以这里就再记录下 ,大家一起懒一起浮躁,呵呵. 0.基础知识 通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性 ...

  6. 全面剖析Smarty缓存机制一[三种缓存方式]

    今天主要全面总结下Smarty模板引擎中强大的缓存机制,缓存机制有效减少了系统对服务器的压力,而这也是很多开发者喜欢Smarty的原因之一,由于篇幅较大,便于博友阅读,这篇文章将剖析Smarty缓存的 ...

  7. C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路

    C#不用union,而是有更好的方式实现   用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...

  8. [.net 面向对象程序设计进阶] (14) 缓存(Cache) (一) 认识缓存技术

    [.net 面向对象程序设计进阶] (14) 缓存(Cache)(一) 认识缓存技术 本节导读: 缓存(Cache)是一种用空间换时间的技术,在.NET程序设计中合理利用,可以极大的提高程序的运行效率 ...

  9. Django2.2 Cache缓存的设计以及几种方式的 多级或单级缓存处理

    首先照例说明一下缓存的作用以及Django中可以用到的缓存方式: 缓存的作用是用于数据项的再次加载,在设定的时间内可以无压力刷新或者再次访问该数据信息 方式一数据库缓存(Django原生的---有代码 ...

随机推荐

  1. 【windows 操作系统】协程

    ◆ 协程 由程序员手动切换. 属于线程,是在线程里面跑的,因此协程又称微线程和线程等.由于不用进行线程上下文切换,因此效率会更高. 资源: 拥有自己的栈空间,大小动态调整. 安全性: 拥有自己的寄存器 ...

  2. Educational Codeforces Round 110 A-D 题解

      A. Fair Playoff 题目大意:有4个人进行比赛,第一个和第二个比,第三个和第四个比,之后各自的胜者再比,最开始每个人持有一个数字,每场比赛持有数字较大的选手会胜出,问最开始持有数字最大 ...

  3. AlertDialog的五种样式

    建立DialogActivity.java文件: 1 public class DialogActivity extends AppCompatActivity { 2 private Button ...

  4. 配置异常拦截处理以及与javabean字段验证的完美结合

    Spring 3.2提供了强大的新注解   @ControllerAdvice,主要是用来Controller的一些公共的需求的低侵入性增强提供辅助,作用于@RequestMapping标注的方法上. ...

  5. ubuntu 下的ftp安装及root身份远程配置

    第一步:在 Ubuntu 中安装 VSFTPD 服务器 //安装 VSFTPD 二进制包 $ sudo apt-get update $ sudo apt-get install vsftpd //使 ...

  6. XML序列化与反序列化接口对接实战,看这篇就够了

    关键字:c# .NET XML 序列化 反序列化 本文为接口对接实践经验分享,不对具体的XML概念定义进行阐述:涉及工具类及处理方法已在生产环境使用多年,可放心使用.当然如果你发现问题,或有不同想法, ...

  7. WPF绘制图表-LiveCharts

    LiveCharts是一款非常好用的WPF图表绘制类库,相比其他同类类库,LiveCharts的UI风格样式更加多样更加美观.  准备工作:安装以下两个类库: 1.甘特图 前台View代码 1 < ...

  8. .NetCore Web Api 利用ActionFilterAttribute统一接口返回值格式

    .Net Core 同 Asp.Net MVC一样有几种过滤器,这里不再赘述每个过滤器的执行顺序与作用. 在实际项目开发过程中,统一API返回值格式对前端或第三方调用将是非常必要的,在.NetCore ...

  9. tensorflow源码解析之framework-graph

    目录 什么是graph 图构建辅助函数 graph_transfer_info 关系图 涉及的文件 迭代记录 1. 什么是graph graph是TF计算设计的载体,如果拿TF代码的执行和Java代码 ...

  10. js开发文档生成工具jsdoc安装使用

    1.全局安装jsdoc,需要先安装node环境哦~ npm install -g jsdoc 2.在项目根目录新建文件conf.json,内容如下: { "tags": { &qu ...