第一次接触到Cache的时候,是在WebForm中,第一次接触,我就再也没能忘记,cache(擦车,的拼音)
客户端浏览器缓存https://blog.csdn.net/y874961524/article/details/61419716
CDN缓存原理https://www.cnblogs.com/shijingxiang/articles/5179032.html
阿里云CDN开启设置https://jingyan.baidu.com/article/948f5924f1d642d80ff5f980.html
有句话叫做,系统性能优化的第一步,就是使用缓存,所以,缓存真的很重要
缓存:
实际上是一种效果&目标,就是获取数据点时候,第一次获取之后找个地方存起来,后面直接用,这样一来可以提升后面每次获取数据的效率。读取配置文件的时候把信息放在静态字段,这个就是缓存。缓存是无处不在的。
我们来请求一个网站,打开开发人员工具
客户端缓存的好处:
1、缩短网络路径,加快响应速度
2、减少请求,降低服务器压力
浏览器缓存究竟是怎么做到的?
打开一个网页,浏览器-----请求---服务器---处理请求会发响应------浏览器展示
Http协议,数据传输的格式(协议,就像是两人交流,都用什么语言)
信息是否缓存,一定是服务器控制的。ResponseHeader--Cache---Control来指定下缓存策略,浏览器看到了这个,就去存储一下。
第一次请求服务器:
再一次请求服务器
DNS是互联网的第一跳,DNS缓存就是CDN,内容分发网络,CDN就是加速缓存的
没有用CDN的请求:
使用了CDN缓存
反向代理:
1、隔离网络,保护服务器(节约公共IP)
2、网络加速,反向代理双网卡
3、负载均衡
4、缓存(跟CDN,也是识别一下header,压缩到一个物理路径/内存)
为什么叫反向代理?因为他就是一个代理,一般的代理,是客户端和服务器之间,有一个代理,去做处理的。但是这个代理是安装在服务器端的。
几种缓存套路相同,但是位置不同,影响的范围也不同。
客户端缓存:只影响当前用户
CDN缓存:针对一批用户
反向代理缓存:针对全部用户。
客户端缓存,存在内存或者硬盘,下次直接用。Cookie,存在内存或者硬盘,浏览器每次请求服务器都会带上的信息。
什么时候用缓存?
1、重复请求,100人访问首页,每个人其实做的都一样,不就是重复
2、耗时好资源
3、结果没变的
下面有一个第三方数据存储和获取的地方:
/// <summary>
/// 第三方数据存储和获取的地方
/// </summary>
public class CustomCache
{
/// <summary>
/// private:私有一下数据容器,安全
/// static:不被GC
/// 字典:读写效率高
/// </summary>
private static Dictionary<string, object> CustomCacheDictionary = new Dictionary<string, object>();
public static void Add(string key, object oVaule)
{
CustomCacheDictionary.Add(key, oVaule);
}
/// <summary>
/// 要求在Get前做Exists检测
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T Get<T>(string key)
{
return (T)CustomCacheDictionary[key];
}
public static bool Exists(string key)
{
return CustomCacheDictionary.ContainsKey(key);
}
public static T GetT<T>(string key, Func<T> func)
{
T t = default(T);
if (!CustomCache.Exists(key))
{
t = func.Invoke();
CustomCache.Add(key, t);
}
else
{
t = CustomCache.Get<T>(key);
}
return t;
}
}
知识兔存取数据的唯一标识:1 唯一的 2 能重现
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"获取{nameof(DBHelper)} {i}次 {DateTime.Now.ToString("yyyyMMdd HHmmss.fff")}");
//List<Program> programList = DBHelper.Query<Program>(123);
List<Program> programList = null;
string key = $"{nameof(DBHelper)}_Query_{123}";
//存取数据的唯一标识:1 唯一的 2 能重现
//if (!CustomCache.Exists(key))
//{
// programList = DBHelper.Query<Program>(123);
// CustomCache.Add(key, programList);
//}
//else
//{
// programList = CustomCache.Get<List<Program>>(key);
//}
programList = CustomCache.GetT<List<Program>>(key, () => DBHelper.Query<Program>(123));
}
知识兔/// <summary>
/// 数据库查询
/// </summary>
public class DBHelper
{
/// <summary>
/// 1 耗时耗资源
/// 2 参数固定时,结果不变
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="index"></param>
/// <returns></returns>
public static List<T> Query<T>(int index)
{
Console.WriteLine("This is {0} Query", typeof(DBHelper));
long lResult = 0;
for (int i = index; i < 1000000000; i++)
{
lResult += i;
}
List<T> tList = new List<T>();
for (int i = 0; i < index % 3; i++)
{
tList.Add(default(T));
}
return tList;
}
}
知识兔缓存优化性能,核心就是结果重用,下次请求还是上一次的结果。如果数据库中有变化,岂不是用了一个错误的数据?是的,缓存是难免的,缓存难免会有脏数据,当然了,我们也会分门别类的去尽量减少脏数据。
用户--角色--菜单,用户权限查的多+比较耗资源+相对稳定,非常适合缓存,缓存方式应该是用户id为key,菜单列表作为value。
string name = "bingle";
List<string> menu = new List<string>();
if (!CustomCache.Exists(name))
{
menu = new List<string>() { "123", "125553", "143", "123456" };
CustomCache.Add(name, menu);
}
else
{
menu = CustomCache.Get<List<string>>(name);
}
知识兔假如bingle的权限变化了,缓存应该失效。数据更新影响单挑缓存,常规做法是Remove而不是更新,因为缓存只是用来提升效率的,而不是数据保存的,因此不需要更新,只需要删除就好,如果真的下次用上了,到时候再去初始化。
CustomCache类增加删除缓存的方法:
知识兔public static void Remove(string key) { CustomCacheDictionary.Remove(key); }