内存缓存是在 asp.net core 程序的进程中 存储的。如果程序 重新启动 以前的缓存 将全部清除
下面是 笔者 自写的例程 声明:所有文章 都是 通过 .net6 进行演示的,如果 不同版本 笔者会标明
1.首先 需要在 Program.cs 的配置文件中 添加 服务
builder.Services.AddMemoryCache();
2.创建 测试的 实体 Book.cs
namespace aspnetcore009
{
public record Book(long id,string name);
}
3.创建 例程 中的 DBcontext.cs
namespace aspnetcore009
{
//为了演示 模拟从数据库中取 数据
public class DBcontext
{
public static async Task<Book?> GetBook(long id)
{
switch (id)
{
case 0:
return await Task.FromResult(new Book(1, "红楼梦"));
case 1:
return await Task.FromResult(new Book(2, "西游记"));
case 2:
return await Task.FromResult(new Book(3, "水浒传"));
default:
return null;
}
}
}
}
4.测试程序
强烈 建议 使用 GetOrCreateAsync 方法,它可以自然的解决缓存穿透问题,可以把不存在的数据 也可以 设置为 缓存,避免恶意程序造成的 缓存穿透
什么是缓存穿透
缓存穿透最直白的意思就是,我们的业务系统在接收到请求时在缓存中并没有查到数据,从而穿透到了后端数据库里面查数据的过程。
什么是缓存雪崩?
当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库崩溃。
缓存雪崩 解决办法:就是 在 设置缓存 过期时间中 进行 范围 随机 推荐使用 Random.Shared.Next(5,10) 避免高并发时 会取到相同 值
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
namespace aspnetcore009.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class TestController : ControllerBase
{
private readonly IMemoryCache _memoryCache;
//依赖注入 内存缓存
public TestController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
[HttpGet]
public async Task<ActionResult<Book?>> GetBookId(long id)
{
Console.WriteLine("开始访问GetBookId方法");
var book = await _memoryCache.GetOrCreateAsync("book" + id, async e =>
{
Console.WriteLine("需要到数据库中查询数据");
//绝对过期时间
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30);
//滑动过期时间
e.SlidingExpiration =TimeSpan.FromSeconds(10);
//设置随机 缓存过期时间 解决 缓存雪崩
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Random.Shared.Next(5,10));
return await DBcontext.GetBook(id);
});
Console.WriteLine($"返回的数据为{book}");
if (book == null)
{
return NotFound($"没有{id}的书籍");
}
else
{
return book;
}
}
}
}
服务器 内存缓存 的时间策略 分为 以下 几种
1.通过 AbsoluteExpirationRelativeToNow 属性 设置 绝对过期时间 --指的是 设定了时间,到了某时间后 会自动清除 缓存
2.通过 SlidingExpiration 属性 设置 滑动过期时间 -- 值的是 设定了时间,如果在设定的时间段没有一次访问,这个时间到期 就会清除 缓存,如果在 这个时间没有 到期 时 一直访问 就会 一直自动续时
3.可以 手动 删除 缓存。 这样操作 比较 麻烦。不推荐
如果没有缓存时间策略 缓存会一直保留,除非重启服务端程序,
下面不考虑 缓存时间策略 执行的 结果 分别是
第一次:结果
开始访问GetBookId方法
需要到数据库中查询数据
返回的数据为Book { id = 2, name = 西游记 }
第二次:结果
开始访问GetBookId方法
返回的数据为Book { id = 2, name = 西游记 }
第三次:结果
开始访问GetBookId方法
返回的数据为Book { id = 2, name = 西游记 } .......
运行结果可以看到,一直返回 缓存数据