前言
本地缓存又称为服务器缓存,存储与服务端的缓存,与之前的客户端缓存反向代理缓存不同,本地缓存主要用于存储一些常用的数据,由于每个请求进入服务端获取数据都要进行一系列的计算以及数据库操作,加了缓存之后,请求进如服务端之后先查找缓存,缓存中有需要的数据就直接返回,否则才去进行计算,然后记录缓存;这样的做法就导致了数据库与服务器压力降低,当然也有缺点,那就是实时性,没加入缓存之前是每次都去访问数据库,很显然这样做会导致数据库压力爆棚,但是获取的数据是最新的,而缓存的数据可能会与数据库不一致,通过一些策略可以改善,但也不是绝对的一致,需要进行取舍。
实现
.Net Core 中内置了MemoryCache,我们就用它了,首先Nuget 一下Microsoft.Extensions.Caching.Memory
下载完成后,进入Startup中的ConfigureServices进行注册;
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddMemoryCache(); }
接下来就能使用了,使用与其他服务一样,先进行注入,然后就能使用了,这里写了几句简单的代码,一个不过期缓存nowKey,一个随机事件过期缓存randomKey。
private readonly IMemoryCache _memoryCache; public HomeController(IMemoryCache memoryCache) { this._memoryCache = memoryCache; } public IActionResult Index() { string nowKey = "Now"; string randomKey = "Random"; string date= string.Empty; string num = string.Empty; if (!_memoryCache.TryGetValue(randomKey, out num)) { var r = new Random().Next(10, 20); num = r + $"秒后过期 起始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}"; _memoryCache.Set(randomKey, num, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(r))); } if (!_memoryCache.TryGetValue(nowKey, out date)) { date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"); _memoryCache.Set(nowKey, date); } ViewBag.DateCache = date; ViewBag.RandomCache = num; return View(); }
»MemoryCache的过期策略有绝对过期时间,也有相对过期时间,上面的过期时间使用的是绝对过期时间,从set之后开始计时,超过一段时间后过期;相对过期时间是指超过一段时间没调用后过期,如果设置缓存后开始计时这时有一个缓存进来会重新计时。
效果
打开多个窗体同时访问localhost:8878/Home/Index端口,效果如下
可以看到上面的时间缓存与下面的缓存三个窗体一致,说明这两个缓存存储在服务端内存中。访问本服务端都拿到一样的值。
下面看看同时运行多个实例
三个实例的缓存不一致,原因当然很简单,因为三个实例为三个进程,而进程间互相隔离,所以他们只能访问到存在自己进程中存储缓存的内存,从而导致不一致。如果把一个实例当成单机,三个实例即一个集群,他们之间内存并不共享,这就需要分布式缓存了,下一篇说。
总结
回到本地缓存,本地缓存的作用还是减轻服务器和数据库的压力,拦截到请求先在缓存中查找,缓存没找到才去计算或者数据库取,这样可以提升服务器访问量以及响应速度,有较明显的性能提升。