缓存 Caching
利用缓存可以让系统的性能得到极大的提升。
缓存命中:从缓存中获取了需要的数据就称缓存命中。
命中率:多次请求中命中的请求占全部请求次数的百分比。即:缓存命中/全部缓存请求=命中率
过期策略:
- 绝对时间
- 滑动时间:指定一段时间,如果在这段时间有访问,则自动续期
- 绝对时间+滑动时间:能保证即是频繁访问的数据,在一个最终的时间段里也会过期。
过期策略选择:
- 绝对时间:用于频繁访问,而且不常变更的基础数据。
- 滑动时间:用于访问量少,而且经常会改变的数据。
- 绝对时间+滑动时间:用于频繁访问,而且经常改变的数据。经对时间要设置比滑动时间要长
缓存问题:
缓存穿透:要缓存的数据在数据库中不存在,导致每次请求都访问数据库。
解决方案:把查不到数据当为 null 空值存入缓存。
缓存雪崩:假如用户的登录系统时,集中加载一些基础数据,且设置的过期时间都一样,当到了过期时间后,缓存会集中过期,导致大量的数据库请求访问 ,数据库服务器会出现周期性压力。
解决方案:在写缓存时,在基础过期时间之上,再加一个随机的过期时间,这样缓存就会分布在一个时间段,而不会出现缓存集中一个时间点全部过期。
缓存数据混乱:
A用户缓存的数据,可能被B用户拿去使用。
解决方案:合理设置缓存ID,例如:UserInfo+UserId
一、响应缓存
[ResponseCache(Duration =60)] public IActionResult Index() { return View(DateTime.Now); }
二、内存缓存
//注册服务器内存缓存 builder.Services.AddMemoryCache();
提示:ASP.NET Core MVC 项目,框架会自动注入内存缓存服务。
客户端使用内存缓存,主要是调用:IMemoryCache 接口。
因为从数据库获取数据比较耗时, 所以一般都用异步方法。
1 using Microsoft.AspNetCore.Mvc; 2 using Microsoft.EntityFrameworkCore; 3 using Microsoft.Extensions.Caching.Memory; 4 using MvcMovie.Data; 5 using MvcMovie.Models; 6 7 namespace MvcMovie.Controllers 8 { 9 public class CacheTestController : Controller 10 {//缓存 11 private readonly ILogger<CacheTestController> _logger; 12 private readonly MvcMovieContext _dbContext; 13 private readonly IMemoryCache _memoryCache; 14 15 public CacheTestController(MvcMovieContext dbContext, ILogger<CacheTestController> logger, IMemoryCache memoryCache) 16 { 17 _dbContext = dbContext; 18 _logger = logger; 19 _memoryCache = memoryCache; 20 } 21 22 public async Task<IActionResult> Index() 23 { 24 _logger.LogInformation($"开始请求数据:{DateTime.Now.ToString()}"); 25 List<Employee>? employees = await _memoryCache.GetOrCreateAsync("AllEmployee", async e => 26 {//仅当从缓存中找不到键为AllEmployee的缓存时,才会执行以下代码从数据库中拿取数据 27 //并且将取得的数据缓存到内存中。 28 //1.绝对过期策略,10秒后过期 29 //e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10); 30 //2.滑动过期策略,10秒之内有访问就续期,超过10秒无访问就过期 31 e.SlidingExpiration=TimeSpan.FromSeconds(10); 32 _logger.LogInformation($"从数据库中获取数据:{DateTime.Now.ToString()}"); 33 return await _dbContext.Employees.ToListAsync(); 34 }); 35 _logger.LogInformation($"请求完成:{DateTime.Now.ToString()}"); 36 return View(employees); 37 } 38 } 39 }