学海无涯

导航

缓存

缓存的优点

  • 提高网站的访问速度
  • 适用 于不易改变的数据

缓存的位置

  • 服务器端(Web服务器 In-Memory 内存缓存)
  • 缓存服务器(集群服务器)
  • 客户端

一、In-Memory 内存缓存(存在于Web服务器,仅能在一个服务器上使用)

  • 最简单的
  • IMemoryCache
  • 适用 于Sticky Session(粘性会话)
  • 适用 于任何类型的对象
//首先注册服务器内存缓存
builder.Services.AddMemoryCache(); 

设置缓存

 public class MoviesController : Controller
    {
        private readonly MvcMovieContext _context;
        private readonly IMemoryCache m_MemoryCache;

        public MoviesController(MvcMovieContext context, IMemoryCache memoryCache)
        {
            _context = context;
            m_MemoryCache = memoryCache;
        }
        public async Task<IActionResult> List()
        {
            //判断是否在缓存中
            if (!m_MemoryCache.TryGetValue(CacheKeyValue.Movies
                , out List<Movie> cachedMovies))
            {
                cachedMovies = await _context.Movie.ToListAsync();
                //设置缓存过期时间
                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    //.SetAbsoluteExpiration(TimeSpan.FromSeconds(600))//绝对过期时间
                    .SetSlidingExpiration(TimeSpan.FromSeconds(30));//相对活跃时间的滚动过期时间
                //回调函数,即缓存被清除之后调用
                cacheEntryOptions.RegisterPostEvictionCallback(FillCache, this);
                //设置缓存的值 
                m_MemoryCache.Set(CacheKeyValue.Movies, cachedMovies, cacheEntryOptions);
            }
            return View(cachedMovies);
        }
}

二、 Cache Tag Helper 缓存组件

使用方法:

<cache expires-after="@TimeSpan.FromSeconds(30)">
    @await Component.InvokeAsync("xxViewComponent")
</cache>

缓存在服务器端,实际上是使用的 IMemoryCache 

三、分布式缓存(例如:Redis Cache)

特点:

  • 无需 Sticky Session
  • 可扩展
  • 服务器重启不会影响缓存
  • 性能更好

微软提供的分布式缓存接口 IDistributedCache ,存储的数据类型为:byte[ ]

缓存使用的方法如下:

  • Get,GetAsync
  • Set,SetAsync
  • Refresh,RefreshAsync
  • Remove,RemoveAsync

 通过NuGet引用 Microsoft.Extensions.Caching.Redis 程序包

//注册Redis分布式缓存服务
builder.Services.AddDistributedRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "movies";
});

 使用Redis缓存

 public class MoviesController : Controller
    {
        private readonly MvcMovieContext _context;
        private readonly IMemoryCache m_MemoryCache;
        private readonly IDistributedCache m_DistributedCache;

        public MoviesController(MvcMovieContext context, IMemoryCache memoryCache, IDistributedCache distributedCache)
        {
            _context = context;
            m_MemoryCache = memoryCache;
            m_DistributedCache = distributedCache;
        }
        public async Task<IActionResult> List()
        {//Redis缓存
            List<Movie> cachedMovies = null;
            var cacheMovieString = await m_DistributedCache.GetStringAsync(CacheKeyValue.Movies);
            if (cacheMovieString == null)
            {//缓存不存在
                cachedMovies = await _context.Movie.ToListAsync();
                //设置缓存
                var serializedString = JsonSerializer.Serialize(cachedMovies);//序列化为字符串
                //byte[] encodeMovies = Encoding.UTF8.GetBytes(serializedString);

                var cacheEntryOptions = new DistributedCacheEntryOptions()
                    .SetSlidingExpiration(TimeSpan.FromSeconds(30));
                await m_DistributedCache.SetStringAsync(CacheKeyValue.Movies, serializedString, cacheEntryOptions);
            }
            else
            {//读取缓存
                cachedMovies = JsonSerializer.Deserialize<List<Movie>>(cacheMovieString, new JsonSerializerOptions());
            }
            return View(cachedMovies);
        }
}

 四、客户端缓存 Response 缓存

  • 基于 Header
  • 客户端缓存
  • 使用 ResponseCache 这个Attribute

Response 缓存参数

  • Location 缓存放在那
  • Duration 缓存时间长短
  • NoStore 不缓存 
  • VaryByHeader  通过检测 Header 的值来判断是否使用缓存。
builder.Services.AddControllersWithViews(options =>
{
    options.CacheProfiles.Add("Default", new CacheProfile
    {//设置Response缓存
        Duration = 60
    });
});

  

 //方法1:直接写缓存参数
//[ResponseCache(Duration =30,Location = ResponseCacheLocation.Client)]
//方法2(推荐):使用Program.cs 配置文件中的缓存参数
[ResponseCache(CacheProfileName="Default")]
 public async Task<IActionResult> List()
{
//...
}

五、压缩

压缩传输的数据

//压缩传输数据
builder.Services.AddResponseCompression();
var app = builder.Build();
app.UseResponseCompression();//默认使用 gzip

  

 

posted on 2023-02-14 15:11  宁静致远.  阅读(104)  评论(0编辑  收藏  举报