首页 > 其他分享 >Net DB Web多级缓存的实现

Net DB Web多级缓存的实现

时间:2023-03-20 23:56:12浏览次数:57  
标签:Web 缓存 浏览器 cache DB Id 服务器 Net public

1、客户端缓存(浏览器缓存)

  HTTP有一套控制缓存的协议-RFC7234,其中最重要的就是cache-control这个相应报文头,服务器返回时,如果Response带上

cache-control:max-age=5  #表示允许浏览器缓存5秒(仅是允许,浏览器是否缓存还看浏览器本身机制是否要遵循这套缓存协议)

  Net 封装好了一个缓存特性,如:

    public class HomeController : ControllerBase
    {
        [ResponseCache(Duration = 5)]//告诉浏览器可用缓存5秒,Duration必须定义,不然请求会报错
        [HttpGet("GetNowDateTime")]
        public string GetNowDateTime()
        {
            return DateTime.Now.ToString();
        }
    }

  执行多次请求

  

  第一行为首次请求,Response Headers:

cache-control: public,max-age=5   #告诉浏览器进行缓存
content-encoding: gzip
content-type: text/plain; charset=utf-8
date: Sun, 19 Mar 2023 07:17:50 GMT
server: Microsoft-IIS/10.0
vary: Accept-Encoding
x-powered-by: ASP.NET

  后续5s内的请求,都会从缓存中取,Size=disk cache即为缓存,取到的返回值和首次请求一致,直到过了5s,再次向服务器发起请求。

  PS:勾选 Disable cache,发出的请求头 Request Headers会加上

cache-control: no-cache  #不从缓存中取数

2、服务器端缓存

  如果有大量客户端访问服务器获取数据,仅依靠客户端缓存,还是会让服务器多次运行接口程序

  服务端缓存就是为了解决这个问题

  .Net 添加服务器缓存中间件

//app.UseCors(); //跨域,如果有
app.UseResponseCaching();//启动服务器缓存,位置介于这两中间件之间
app.MapControllers();

  UseResponseCaching中间件需要和ResponseCache特性配合使用

  Api代码仍为

    public class HomeController : ControllerBase
    {
        [ResponseCache(Duration = 5)]//告诉浏览器可用缓存5秒
        [HttpGet("GetNowDateTime")]
        public string GetNowDateTime()
        {
            return DateTime.Now.ToString();
        }
    }

  打开两个浏览器访问尝试,功能实现!!!

  不过,这种服务器缓存方式十分鸡肋,存在的限制太多:

a)无法解决恶意请求给服务器带来的压力(Request Header带上了cache-control: no-cache,不仅浏览器不读缓存,服务器也不读)
b)响应码=200的Get或者Head的响应才会被缓存
c)报文头带有Authorization、Set-Cookie等响应,不会缓存

 3、内存缓存

  内存缓存需要自身在代码定义,仅针对业务层面的缓存,不受请求头影响

  添加内存缓存服务

builder.Services.AddScoped<IDBHelper, SqlServerHelper>(); //db注入
builder.Services.AddMemoryCache();//内存缓存

  模拟SqlServerHelper类

namespace DIDemo.Services
{
    public record Staff(int Id, string acc);
    public class SqlServerHelper : IDBHelper
    {
        List<Staff> _staff_list = new List<Staff>();
        public SqlServerHelper() {
            _staff_list.Add(new Staff(1,"tom"));
            _staff_list.Add(new Staff(2,"jerry"));
        }public Staff? GetStaff(int Id)
        {
            return this._staff_list.Find(x => x.Id == Id);
        }
    }
}

  定义一个查询员工的接口

using DIDemo.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace DIDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly IDBHelper _db;
        private readonly IMemoryCache _menCache;

        public HomeController(IDBHelper db, IMemoryCache menCache)
        {
            _db = db;
            _menCache = menCache;
        }

        [HttpGet("GetStaff")]
        public  ActionResult<Staff> GetStaff(int Id)
        {
            Console.WriteLine("begin");
            //1、从缓存取数据   2、缓存取不到,从数据库取,添加缓存
            var items =  _menCache.GetOrCreate<Staff>($"staff_{Id}",  (e) =>
            {
                Console.WriteLine("缓存不存在,开始写缓存");
                e.AbsoluteExpirationRelativeToNow= TimeSpan.FromSeconds(15); //15s后过期
                e.SlidingExpiration = TimeSpan.FromSeconds(5); //5s滑动过期:5s内访问过缓存,会重新开始计算5s
                return _db.GetStaff(Id);
            });
            if (items == null)
            {
                return NotFound($"员工ID={Id},不存在");
            }
            return items;
        }
    }
}

  GetOrCreate,如果获取不到,就通过委托,查询数据库并写入缓存

  AbsoluteExpirationRelativeToNow:固定的过期时间

  SlidingExpiration:滑动过期时间

  两个时间可用单独定义,也可以一起定义,其中一个过期即为过期,通常不单独使用SlidingExpiration,可能造成缓存无限续命

4、分布式缓存

  涉及微服务,负载均衡,需要一个集中管理的缓存服务,也就是我们的分布式缓存

  老生常谈的Redis,看看以前写的文章吧!

  c# 使用 Redis   缓存Redis

 

标签:Web,缓存,浏览器,cache,DB,Id,服务器,Net,public
From: https://www.cnblogs.com/wskxy/p/17233325.html

相关文章

  • ASP.NET MVC Filters 4种默认过滤器的使用
    过滤器(Filters)的出现使得我们可以在ASP.NETMVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户,过滤器理论上有以下功......
  • 理解ASP.NET Core - 过滤器(Filters)
    Filter概览如果你是从ASP.NET一路走过来的,那么你一定对过滤器(Filter)不陌生。当然,ASP.NETCore仍然继承了过滤器机制。过滤器运行在过滤器管道中,这是一张官方的图,很好地......
  • 113webpack
    WebpackWebpack是一个现代化的JavaScript应用程序打包工具,它可以将多个JavaScript文件、CSS、图片等资源打包成一个或多个静态资源文件,以便在网页中使用。Webpack在前端......
  • adb命令启动报错Error: unknown command '-start'怎么办
    大家好,每天记录小问题.水滴石穿.今天介绍一个从0开始启动app应用的app命令adbshellam-start-w-n包名/启动名第一次运行时报错  怎么办呢,这边使用的是雷电......
  • 每日双人总结——web地铁查询
    <!DOCTYPEhtml><html><head><metacharset="UTF-8"><!--重要meta,必须!--><metaname="viewport"content="width=320,initial-scale=1.0,maximum-s......
  • 从0到1构建springboot web应用镜像并使用容器部署
    文章目录​​一、生成镜像的两种方法​​​​1.1、使用commit生成镜像​​​​1.1.1、拉取Centos基础镜像​​​​1.1.2、启动Centos容器并安装Go​​​​1.1.3、commit生成......
  • 在Struts2获得WebApplicationContext的方法
    1.Action实现implementsServletRequestAware,并实现setServletRequest()方法。publicvoidsetServletRequest(HttpServletRequestrequest){......
  • .Net MVC + EChart 实现动态生成统计图表
    数据库信息:数据库名称:chart   表名:goods   后端代码:1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Data;4......
  • NETCONF、XML、YANG之间的关系
    目录NETCONF、XML、YANG之间的关系参考引用理解XMLYANG操作层数据库基本能力标准能力集扩展能力集总结NETCONF、XML、YANG之间的关系参考引用https://support.huawei.co......
  • Android Studio通过jdbc连接MySQL
    1、下载MySQL-connector-jave.jar包地址如下:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.46 2、将jar包移到如图所示的位置,然后右键addasl......