.Net Core缓存及问题规避

2023-11-16

目录

一、什么是缓存

二、客户端响应缓存

三、服务器端响应缓存

四、内存缓存

五、缓存穿透问题的规避

六、缓存雪崩问题的规避 

七、缓存数据混乱的规避

八、分布式缓存

 九、缓存方式的选择


一、什么是缓存

       缓存是系统优化中简单又以有效的工具,只要简单几行代码或者几个简单的配置,我们就可以利用缓存让系统的性能得到极大的提升。缓存是一个用来保存数据的区域,从缓存区域中度读取数据的速度比数据源读取数据的速度快很多。在从数据源获取数据之后,我们可以把数据保存在缓存中。下次再需要获取同样数据的时候,我们可以直接从缓存中获取之前保存的数据,而不需要再去数据源获取数据。

由于从缓存中读取数据的速度比从数据源中读取数据的速度更快,因此使用缓存能提高系统数据的获取速度。如果从缓存中获取了要获取的数据,就叫做“缓存命中”;多次请求中,命中的请求占全部请求的百分比叫做“命中率”;如果数据源中的数据保存到缓存后,发生了变换,就会导致“缓存数据不一致”。

二、客户端响应缓存

        RFC 7234是HTTP中对缓存进行控制的规范,其中重要的是cache-control响应报文头。假如浏览器向服务器请求/Person/1这个路径,如果服务器给浏览器端的响应报文头中cache-control的值为max-age=60,则表示服务器指示浏览器端“可以缓存这个响应内容60s”。在60s内,如果用户要求浏览器再次向/Person/1发送请求的话,浏览器就可以直接使用保存的缓存内容,而不是向服务器再次发出请求。

        在 ASP.NET Core 中,我们一一般不需要手动控制响应报文头中的cache-control,只要给需要进行缓存控制的控制器的操作大 方法添加ResponseCacheAttribute这个 Attribute即可,ASP.NET 
Core 会根据 ResponseCacheAttribu ite 的设置来生成合适的 cache-control响应报文头。

三、服务器端响应缓存

          如果我们在ASPNET Core 中安装了“响应缓存中间件”,ASP.NET Core 不仅会继续根据[ResponseCache]设置来生成 cache-control 响应报文头以设置客户端缓存,还会在服务器端也按照[ResponseCache]的设置来对响应进行服务器端缓存。如果有启用“响应缓存中间件”,那么当 A、B、C这3个浏览器分别向/Test1/Now 路径发送请求的时候,服务器端的 Now 方法会执行 3 次:如果启用了“响应缓存中间件”,当A、B、C这个浏览器分别向/Test1/Now 路径发送请求的时候,只要后面两次请求的时间在 60s 内,服务器端的 Now 方法只会执行1次,后两次请求虽然也会到达服务器,但是服务器会把第 1次响应的缓存内容直接返回,而不会执行 Now 方法。很显然,使用响应缓存中间件在服务器端实现响应缓存有两个好处:第一,提升没有实现缓存机制的客户端获取数据的速度,因为虽然请求仍然到达了服务器,但服器端缓存直接返回了缓存的响应,避免了从执行速度缓慢的数据源获取数据的性能问题;第二,对于实现了缓存机制的客户端也能降低服务器端的压力,因为如果没有启用响应缓存中间件,那么如果在短时间内服务器端收到了来自一万个不同客户端到/TestI/Now 的请求,那么 Now 方法仍然会行一万次,因为客户端的缓存是由每个客户端自己管理的:如果启用了响应缓存中间件,Now方法只会执行一次,这降低了服务器端的压力。
启用响应缓存中间件的步骤很简单,除了给控制器中需要进行缓存控制的操作方法标注[ResponseCache]之外,我们只要在ASP.NET Core项目的Program.cs的app.MapControllers之前加上app.UseResponseCaching即可。

四、内存缓存

       除了响应缓存中间件这样自动化的服务器端缓存机制之外,ASP.NET Core还提供了允许开发人员手动进行缓存管理的机制,内存缓存就是一种把缓存数据放到应用程序内存中的机制,内存缓存中保存的是一系列的键值对,就像 Dictionary 类型一样,每个不同的缓存内容有不同的“缓存键”,每个缓存键对应一个“缓存值”。我们可以设置缓存的键值对,也可以根据缓存键取出缓存中保存的缓存值。内存缓存的数据保存在当前运行的网站程序的内存中,是和进程相关的。因为在 Web服务器中,多个不同网站是运行在不同的进程中的,所以不同网站的内存缓存是不会互相干扰的而且网站重启后,内存缓存中的所有数据也就都被清空了。对于ASP.NET Core MVC 项目,框架会自动地注入内存缓存服务:对于ASP.NET Core WebAPI等没有自动注入内存缓存服务的项目,我们需要在 Program.cs 的 builder.Build 之前添builder.Services.AddMemoryCache 来把内存缓存相关服务注册到依赖注入容器中。

IMemoryCache接口中的一些方法

 

五、缓存穿透问题的规避

在使用内存缓存的时候,如果处理不当,我们容易遇到“缓存穿透”的问题。在IMemoryCache接口中有一个Get方法,它根据缓存键key查找缓存值,如果找不到缓存项,则方法会返回null等默认值,使用缓存的方法

 

六、缓存雪崩问题的规避 

在使用缓存的时候,有事会有在很短时间内,程旭把一大批数据从数据源加入缓存的情况。比如为了提升网站的运行速度,我们会对数据进行“预热”,也就是在网站启动的时候把一部分数据从数据库中读取出来并加入缓存。如果这些数据设置的过期时间都相同,到了过期时间的时候,缓存项会集中过期,因此优惠导致大量的数据库请求,这样数据库服务器就会出现周期性的压力,这种陡增的压力甚至会把数据库服务器“压垮”(崩溃),当数据库服务器从崩溃中恢复后,这些压力有过来了,从而造成数据库服务器反复崩溃,恢复,这就是数据库服务器的“雪崩”。

解决方法就是写缓存时,在基础过期时间之上,再加一个随机的过期时间这样缓存项的过期时间就会均匀地分布在一个时间段内。

七、缓存数据混乱的规避

在使用服务器端缓存的时候,如果处理不到程序,有可能造成缓存数据混乱等严重的问题。

 

       上面的代码使用“UserInfo”作为缓存键。当A 用户访问代码 7-33 所示的接口的时候,第5行代码查询到了A 用户的个人信息,然后数据被写入到缓存中;当B 用户也来访问这个接口的时候,由于缓存中已经存在缓存键为“Usernfo”的缓存内容,因此网站就直接把缓存中的数据返回给 B用户了,但是缓存中的用户信息是A用户的,这就造成了 B用户看到A用户信息的数据泄露问题。解决这种问题的核心就是要合理设置缓存的 ID。很显然,在代码中用缓存键“UserInfo”加上当前用户的ID就可以避免这个问题,也就是用 UserInfotuserld作为缓存键。

八、分布式缓存

       由于内存缓存把混的数据保存在web应用的内存中,因此数据的读写速度是非常快的,但是在分布式系统中这些缓存数据是不能共享的,因此集群中的每个节点中的web应用都要加载一份数据到自己的内存缓存中。

在NuGet安装Redis,然后注册Redis缓存

 然后要编写代码来通过IDistributedCache读写Redis中的缓存数据

 

 九、缓存方式的选择

.NET 中的缓存分为客户端响应缓存、服务器端响应缓存、内存缓存、分布式缓存等。缓存可以极大地提升系统的性能,在进行系统设计的时候,根据系统的特点选择合适的缓存方式。客户端响应缓存能够充分利用客户端的缓存机制,它不仅可以降低服务器端的压力,也能然提升客户端的操作响应速度并且降低客户端的网络流量。但是需要合理设置缓存相关参数,以避免客户端无法及时刷新到最新数据的问题。服务器端响应缓存能够乎不需要编写额外的代码就轻松地降低服务器的压力。但是由于服务器端响应缓存的启用条件比较苛刻,因此要根据项目的情况决定是否使用它。内存缓存能够降低数据库以及后端服务器的压力,而且内存缓存的存取速度非常快; 分式缓存能够让集群中的多台服务器共享同一份缓存,从而降低数据源的压力。如果集群节点的数量不多,并且数据库服务器的压力不大的话,推荐读者使用内存缓存,毕竟内存的读写速度比网络快很多;如果集群节点太多造成数据库服务器的压力很大的话,可以采用分布式缓存。无论是使用内存缓存还是分布式缓存,我们都要合理地设计缓存键,以免出现数据混乱。这些缓存方式并不是互斥的,我们在项目中可以组合使用它们。比如对于论坛系统,论坛首页中的版块信息变动不频繁,我们可以为版块信息的客户端响应缓存设置 24h 的过期时间;对于所有的帖子详情信息,我们同时启用内存缓存和分布式缓存,当加载帖子详情页面的数据的时候,我们先到内存缓存中查找,内存缓存中找不到再到分布式缓存中查找,这样就既可以利用内存缓存读取速度快的优点,也能利用分布式缓存的优点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net Core缓存及问题规避 的相关文章

随机推荐

  • 机器学习基础-监督学习与无监督学习

    机器学习基础 监督学习与无监督学习 机器学习 Machine Learning 主要研究计算机系统对特定任务的性能 逐步进行改善的算法和统计模型 通过输入海量数据对模型进行训练 使模型掌握数据所蕴含的潜在规律 进而对新输入的数据进行准确的分
  • C#循环语句 for 与 while 以及关键字跳出循环 C#学习杂记(四)

    1 for循环 1 for 循环有一个基本固定的写法 for int i 0 i lt 10 i 类似这样 for int i 0 i lt 10 i Console WriteLine i 循环十次 打印 i 2 for 循环简单应用 求
  • 【华为OD机试真题2023 JAVA&JS】寻找核酸检测点

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 寻找核酸检测点 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 张三要去外地出差 需要做核酸 需要在指定时间点前做完核酸 请帮他找到满足条件的核酸检测点 1 给出
  • Python网页请求超时如何解决

    在进行网络爬虫项目时 我们经常需要发送大量的请求来获取所需的数据 然而 由于网络环境的不稳定性 请求可能会因为超时而失败 请求超时可能导致数据获取不完整 影响爬虫的效率和准确性 此外 频繁的请求超时可能会被目标网站视为恶意行为 导致IP被封
  • 用Python搭建http文件下载服务器

    写这篇主要是为了Assetbundle 二 热更新方案设计 中涉及的下载服务器搭建 Python功能能强大 用起来也很方便 我们在做资源更新模块时 需要搭建一个http文件下载服务器 用于模拟从外网下载Assetbundle等 有很多种方法
  • nginx配置多个server

    nginx配置多个server server listen 80 server name localhost root C Users Administrator Desktop dist location try files uri in
  • Android 9.0修改recovery 菜单项字体大小

    1 前言 在Android9 0rom定制化开发中 在原生系统中 对于recovery模块这部分也是相当重要的部分 所以当进入recovery模式后 界面会g menu actions 菜单选项和 提示文字 而这些文字的 大小不像上层一样是
  • E: Unmet dependencies. Try ‘apt --fix-broken install‘ with no packages (or specify a solution).

    ubuntu 安装 dos2unix的时候提示 出错 apt install dos2unix Reading package lists Done Building dependency tree Reading state inform
  • vue仿淘宝购物车的实现

    先看效果图 实现的功能有 1 选中店铺 店铺下的商品全选中 2 店铺下的商品全选中 相对应的店铺也会被选中 3 所有的店铺全选中 底部的全选也会被选中 4 所有的商品全选中 底部的全选也会被选中 5 底部的全选选中 所有的店铺和商品都会被选
  • 【VUE】npm打包报错 Syntax Error: Error: Cannot find module ‘imagemin-gifsicle‘

    一 Syntax Error Error Cannot find module imagemin gifsicle npm run build 报错 报错如下 原因 这个错误消息显示缺少了 imagemin gifsicle 模块 而它是
  • 聚类算法——最大最小距离算法(python实现)

    每篇一句 You re gonna have to face your fear sooner or later 冰河世纪 最大最小距离算法 最大最小距离算法也成为小中取大距离算法 这种方法首先根据确定的距离阈值寻找聚类中心 然后根据最近邻
  • 获取和分析Dump的几种工具简介

    最近在进一步学习support技能的时候 了解到分析Dump的重要性 经过学习 做一些笔记 一 什么是Dump文件 Dump文件时进程的内存镜像 可以把程序的执行状态保存到Dump文件中 Dump文件分为内核模式Dump和用户模式Dump
  • SQL-labs的第26a关——空格和注释被过滤 延时盲注(Get)

    注意该关的or和and也被过滤了 1 判断闭合方式 输入语句 id 1 返回页面如下 我们猜测闭合符号是 再进行验证 输入语句 id 1 00 返回页面如下 依然报错 说明闭合符号除了 之外还有其他的符号 我们输入 id 1 00 返回页面
  • pgsql:远程连接时出现报错“发生致命错误:没有用于主机“…”,用户“…”,数据库“…”,SSL关闭的pg_hba.conf记录“,或者英文乱码

    问题 在用Navicat Premium远程连接pgsql时出现报错 发生致命错误 没有用于主机 用户 数据库 SSL关闭的pg hba conf记录 或者英文乱码 其实是与上述是同一个意思 解决方案 按提示找到pg安装目录下的 data
  • springboot 整合 redis

    springboot 整合 redis 1 导入依赖
  • {CTFshow} 萌新web1 详解

    练习ctf当然不止一个平台啦 所以我打算也写一写ctfshow的题目 好家伙 直接明了 就是让我审计代码 看完发现 我们要用get方式提交 flag在id 1000 但是直接提交id 1000会返回错误 所以我们需要再添加一个id用来防止被
  • springboot 访问远程服务器文件,springboot使用JSch远程读取sshd服务器上的文件

    JSch 是SSH2的一个纯Java实现 它允许你连接到一个sshd 服务器 使用端口转发 X11转发 文件传输等等 你可以将它的功能集成到你自己的 程序中 同时该项目也提供一个J2ME版本用来在手机上直连SSHD服务器 实现一个java工
  • 前后端分离ajax接收文件流的实践

    一般ajax post请求不能实现的原因 开始的想法 在页面上用jQuery的 post方法发送一个请求给服务器 然后服务器根据这个参数再生成相应的一个文件流返回给客户端 但是 在 post方法的回调函数中 只能处理xml json scr
  • 手机android端安装配置cpolar内网穿透

    cpolar作为一款强大的内网穿透工具 能够在不同操作系统平台中得到应用 真正打通了不同操作系统之间的围墙 让我们能方便的从一个操作平台中 读取到另一个操作平台中的数据 甚至对另一操作平台中运行的程序进行调试 今天 我们就为大家介绍 如何在
  • .Net Core缓存及问题规避

    目录 一 什么是缓存 二 客户端响应缓存 三 服务器端响应缓存 四 内存缓存 五 缓存穿透问题的规避 六 缓存雪崩问题的规避 七 缓存数据混乱的规避 八 分布式缓存 九 缓存方式的选择 一 什么是缓存 缓存是系统优化中简单又以有效的工具 只