:::info 概念的概念

  1. 缓存命中
  2. 缓存命中率
  3. 缓存数据不一致

:::

客户端缓存

  1. //Action上面加ResponseCache特性,设置客户端缓存多少秒
  2. [ResponseCache(Duration =20)]
  3. [HttpGet("Now")]
  4. public string Now()
  5. {
  6. return DateTime.Now.ToString();
  7. }

服务端缓存

:::info 通过在program.cs注册使用

app.UseResponseCaching(); //添加服务器缓存

在app.MapControllers();前面添加

如果有用到app.useCors()

app.useCors() 一定要写在缓存之前。

:::

内存缓存(In-memory cache)

:::info

  1. 把缓存数据放到应用程序的内存。内存缓存中保存的是以系列的键值对,就像Dictionary类型一样。
  2. 内存缓存的数据保存在当前运行的网站程序的内存中,是和进程相关的。因为在Web服务器中,多个不同网站是运行在不同的进程中的,因此不同网站的内存缓存是不会相互干扰的,而且网站重启后,内存缓存中的所有数据也就都被清空了。

缓存的过期时间

  1. 解决方法:在数据改变的时候调用remove或者set来删除或者修改缓存(优点:及时);过期时间(只要过期时间比较短,缓存数据不一致的情况也不会持续很长时间)
  2. 两种过期时间策略:绝对过期时间、滑动过期时间

//设置绝对过期时间,到时间点后就会自动过期

  1. e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
  2. //滑动过期时间,在时间段内被请求就会自动续命,在时间段内没有被请求,就会过期
  3. e.SlidingExpiration = TimeSpan.FromSeconds(10);

缓存雪崩问题

  1. 缓存集中过期引起缓存雪崩
  2. 解决办法:在基础过期时间之上,在加一个随机的过期时间

    e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Random.Shared.Next(10, 15));

:::

  1. builder.Services.AddMemoryCache(); //注册内存缓存服务
  2. //构造函数注入缓存服务
  3. private readonly IMemoryCache memoryCache;
  4. public DemoController(IMemoryCache memoryCache)
  5. {
  6. this.memoryCache = memoryCache;
  7. }
  8. [HttpGet("GetByIdCache/{id?}")]
  9. public async Task<ActionResult<Book?>> GetByIdCache(long id)
  10. {
  11. Console.WriteLine("开始GetByIdCache");
  12. Book? book = await memoryCache.GetOrCreateAsync("Book" + id, async (e) =>
  13. {
  14. Console.WriteLine($"缓存里没找到,到数据库查询数据id={id}");
  15. //设置绝对过期时间,到时间点后就会自动过期
  16. // e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
  17. //滑动过期时间,在时间段内被请求就会自动续命,在时间段内没有被请求,就会过期
  18. e.SlidingExpiration = TimeSpan.FromSeconds(10);
  19. return await MyDBContext.GetBookByIdAsync(id);
  20. });
  21. Console.WriteLine("GetOrCreateAsync结果" + book);
  22. if (book == null)
  23. {
  24. return NotFound($"没有ID为[{id}]的书");
  25. }
  26. return book;
  27. }