前言

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

正文

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

  • 提升数据的获取速度

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

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

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

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消息机制框架原理【简单版本】

    windows消息机制框架原理 结合两张图理解 窗口和窗口类 Windows UI 应用程序 (e) 具有一个主线程 (g).一个或多个窗口 (a) 和一个或多个子线程 (k) [工作线程或 UI 线 ...

  2. maven-mvnd安装使用

    目录 安装使用 官方介绍 使用注意 安装使用 下载 https://github.com/apache/maven-mvnd/releases/tag/0.7.1 ,mvnd-0.7.1-darwin ...

  3. Linux主机内存评估手册-从零到无

    --时间:2020年10月22日 --作者:飞翔的小胖猪 文档基于Centos Linux操作系统作为生产服务器运行环境.实时的查看分析当前系统内存的使用情况是否存在内存瓶颈,结合应用及现行业务需求分 ...

  4. AHUACM寒假集训II(线段树)

    B.Mayor's posters POJ2528 题目大意: D.Count Color POJ2777 题目大意:长为 L ( L ≤ 1 0 5 ) L( L\leq10^5) L(L≤105) ...

  5. Qt:QString

    0.说明 区别于QByteArray,QString串是Unicode串,每个元素都是QChar 16-bit UTF-16编码(Unicode) :而QByteArray是8-bit串. 0.1.初 ...

  6. omnet++:官方文档翻译总结(四)

    学习翻译自:Adding Statistics Collection - OMNeT++ Technical Articles Part 5 - Adding Statistics Collectio ...

  7. Python的内置数据结构

    Python内置数据结构一共有6类: 数字 字符串 列表 元组 字典 文件 一.数字 数字类型就没什么好说的了,大家自行理解 二.字符串 1.字符串的特性(重要): 序列化特性:字符串具有一个很重要的 ...

  8. C++_Leecode1 两数之和

    一.题目介绍 1.题目描述 ->给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标. ->你可以假设每种输入只会对应一个答 ...

  9. 学习Java集合

    1.列表  List接口(继承于Collection接口)及其实现类 List接口及其实现类是容量可变的列表,可按索引访问集合中的元素. 特点:集合中的元素有序.可重复: 列表在数据结构中分别表现为: ...

  10. web自动化之selenium(四)元素等待

    隐式等待 说明 隐式等待是通过设置一定时长的等待,让页面上的某些元素能过加载出来,如果超过了设置的时间还没有加载出来则抛出(NoSuchelementException异常),默认单位为"秒 ...