Asp.Net Core 2.0 项目实战(5)Memcached踩坑,基于EnyimMemcachedCore整理MemcachedHelper帮助类。
Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了
Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架
Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载
Asp.Net Core 2.0 项目实战(4)ADO.NET操作数据库封装、 EF Core操作及实例
Asp.Net Core 2.0 项目实战(5)Memcached踩坑,基于EnyimMemcachedCore整理MemcachedHelper帮助类。
Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例
Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密
Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类
Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例
Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录
Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
Asp.Net Core2.0下使用memcached缓存。
Memcached目前微软暂未支持,暂只支持Redis,由于项目历史原因,先用博客园开源项目EnyimMemcachedCore,后续用到的时候在详细完善测试。
MemcachedHelper此类待完善,仅供参考,注释掉66和179行可用。net core下替代HttpContext.Current.Application.Lock()方法暂未找到。
1 public class MemcachedHelper 2 { 3 private static string _DEPEND_ = "mcache_default_depend"; 4 private static string _DICT_CACHE_ = "default_core_depend_dictiaonry"; 5 private static int _EXP_ = 10 * 60; //默认缓存10分钟 6 private static int HH = 3600; //1小时=3600秒 7 8 static readonly object mlock = new object(); 9 private static readonly ILoggerFactory _loggerFacotry = new LoggerFactory(); 10 /// <summary> 11 /// 定义一个静态MemcachedClient客户端,它随类一起加载,所有对象共用 12 /// </summary> 13 private static MemcachedClient mclient; 14 /// <summary> 15 /// 构造函数,连接memcachedcore并为KEYS字典开辟储存空间 16 /// </summary> 17 static MemcachedHelper() 18 { 19 //mclient = MemCached.getInstance(); 20 if (mclient == null) 21 { 22 lock (mlock) 23 { 24 if (mclient == null) 25 { 26 var options = new MemcachedClientOptions(); 27 UtilConf.Configuration.GetSection("enyimMemcached").Bind(options); 28 mclient = new MemcachedClient(_loggerFacotry, new MemcachedClientConfiguration(_loggerFacotry, options)); 29 } 30 } 31 } 32 //在缓存中开辟一个专门用来存储Kyes的字典对象 33 MDictionary_SaveDict(new Dictionary<string, List<string>>()); 34 } 35 36 #region ** 获取缓存 ** 37 /// <summary> 38 /// 获取缓存 39 /// </summary> 40 public static object Get(string key) 41 { 42 key = key.ToLower(); 43 return mclient.Get(key); 44 } 45 #endregion 46 47 #region ** 添加缓存 ** 48 /// <summary> 49 /// 添加单个依赖项的缓存 (最小时间单位为秒) 50 /// </summary> 51 public static void Set(string depend, string key, object obj, int exp) 52 { 53 depend = depend.ToLower(); 54 key = key.ToLower(); 55 56 try 57 { 58 //HttpContext.Current.Application.Lock(); 59 60 //将数据加入缓存 61 mclient.Add(key, obj, exp); 62 63 //HttpContext.Current.Application.UnLock(); 64 65 ////将Keys加入字典 66 //MDictionary_AddKeys(depend, key); 67 } 68 catch (System.Exception ex) 69 { 70 throw new Exception(ex.Message); 71 } 72 } 73 74 #region ++ Set的多种实现方式 75 /// <summary> 76 /// 默认时间 77 /// </summary> 78 public static void Set(string depend, string key, object obj) 79 { 80 MemcachedHelper.Set(depend, key, obj, _EXP_); 81 } 82 /// <summary> 83 /// 默认Depend和时间 84 /// </summary> 85 public static void Set(string key, object obj) 86 { 87 MemcachedHelper.Set(_DEPEND_, key, obj, _EXP_); 88 } 89 /// <summary> 90 /// 默认Depend 91 /// </summary> 92 public static void Set(string key, object obj, int exp) 93 { 94 MemcachedHelper.Set(_DEPEND_, key, obj, exp); 95 } 96 /// <summary> 97 /// 长时间缓存 98 /// </summary> 99 public static void SetLong(string depend, string key, object obj) 100 { 101 int t = 31536000; //1年 = 10 * 365 * 24 * 60 * 60; 102 MemcachedHelper.Set(depend, key, obj, t); 103 } 104 /// <summary> 105 /// 长时间默认depend 106 /// </summary> 107 public static void SetLong(string key, object obj) 108 { 109 int t = 31536000; //365 * 24 * 60 * 60; //1年 110 MemcachedHelper.Set(_DEPEND_, key, obj, t); 111 } 112 public static void SetAllLong(string key, object obj) 113 { 114 int t = 315360000; //365 * 24 * 60; //10年 115 MemcachedHelper.Set(_DEPEND_, key, obj, t); 116 } 117 #endregion 118 119 #endregion 120 121 #region ** 删除缓存 ** 122 /// <summary> 123 /// 删除有依赖项的Keys的缓存 124 /// </summary> 125 public static void RemoveKeys(string depend, string key) 126 { 127 depend = depend.ToLower(); 128 key = key.ToLower(); 129 130 try 131 { 132 //HttpContext.Current.Application.Lock(); 133 134 //删除缓存 135 mclient.Remove(key); 136 137 //删除key 138 MDictionary_RemoveKeys(depend, key); 139 140 //HttpContext.Current.Application.UnLock(); 141 142 } 143 catch (System.Exception ex) 144 { 145 throw new Exception(ex.Message); 146 } 147 } 148 149 /// <summary> 150 /// 删除默认depend的缓存 151 /// </summary> 152 public static void RemoveKeys(string key) 153 { 154 RemoveKeys(_DEPEND_, key); 155 } 156 157 /// <summary> 158 /// 删除整个依赖项 159 /// </summary> 160 public static void RemoveDepend(string depend) 161 { 162 depend = depend.ToLower(); 163 164 try 165 { 166 //获取keys列表 167 List<string> keysList = MDictionary_GetKeys(depend); 168 169 //循环删除数据 170 for (int i = 0; i < keysList.Count; i++) 171 { 172 string k = keysList[i]; 173 //清空缓存Key 174 mclient.Remove(k); 175 ////清空字典下的Key 176 //MDictionary.RemoveKeys(depend, k); 177 } 178 ////清空字典 179 //MDictionary_RemoveDepend(depend); 180 181 } 182 catch (System.Exception ex) 183 { 184 throw new Exception(ex.Message); 185 } 186 } 187 #endregion 188 189 #region --字典管理-- 190 191 #region ** 字典存取 ** 192 /// <summary> 193 /// 取出字典 194 /// </summary> 195 public static Dictionary<string, List<string>> MDictionary_GetDict() 196 { 197 Dictionary<string, List<string>> dict = mclient.Get(_DICT_CACHE_) as Dictionary<string, List<string>>; 198 if (dict == null) 199 { 200 Dictionary<string, List<string>> newDict = new Dictionary<string, List<string>>(); 201 MDictionary_SaveDict(newDict); 202 return newDict; 203 } 204 else 205 { 206 return dict; 207 } 208 } 209 210 /// <summary> 211 /// 存入字典 212 /// </summary> 213 public static void MDictionary_SaveDict(Dictionary<string, List<string>> dict) 214 { 215 //默认保存360天 216 mclient.Add(_DICT_CACHE_, dict, HH * 24 * 360); 217 } 218 219 /// <summary> 220 /// 添加并存入 221 /// </summary> 222 public static void MDictionary_AddToDictAndSave(string depend, List<string> listKeys) 223 { 224 //取出字典 225 Dictionary<string, List<string>> dict = MDictionary_GetDict(); 226 227 //修改或新增字典 228 if (dict.ContainsKey(depend)) 229 { 230 dict[depend] = listKeys; //覆盖 231 } 232 else 233 { 234 dict.Add(depend, listKeys); //新添加 235 } 236 237 //存回 238 MDictionary_SaveDict(dict); 239 } 240 #endregion 241 242 #region ** keys操作 ** 243 /// <summary> 244 /// 根据depend获取Keys列表 245 /// </summary> 246 public static List<string> MDictionary_GetKeys(string depend) 247 { 248 depend = depend.ToLower(); 249 250 Dictionary<string, List<string>> dict = MDictionary_GetDict(); 251 if (dict.ContainsKey(depend)) 252 { 253 return dict[depend]; 254 } 255 return new List<string>(); 256 } 257 258 /// <summary> 259 /// 添加keys到字典 260 /// </summary> 261 public static void MDictionary_AddKeys(string depend, string key) 262 { 263 depend = depend.ToLower(); 264 key = key.ToLower(); 265 266 //添加keys列表 267 List<string> listKeys = MDictionary_GetKeys(depend); 268 if (!listKeys.Contains(key)) 269 { 270 listKeys.Add(key); 271 //添加并存回字典 272 MDictionary_AddToDictAndSave(depend, listKeys); 273 } 274 275 } 276 277 /// <summary> 278 /// 从字典中删除一个Key 279 /// </summary> 280 public static void MDictionary_RemoveKeys(string depend, string key) 281 { 282 depend = depend.ToLower(); 283 key = key.ToLower(); 284 285 List<string> listKeys = MDictionary_GetKeys(depend); 286 if (listKeys.Contains(key)) 287 { 288 listKeys.Remove(key); 289 //添加并存回字典 290 MDictionary_AddToDictAndSave(depend, listKeys); 291 } 292 } 293 294 /// <summary> 295 /// 删除depend下所有的keys列表 296 /// </summary> 297 public static void MDictionary_RemoveDepend(string depend) 298 { 299 depend = depend.ToLower(); 300 301 Dictionary<string, List<string>> dict = MDictionary_GetDict(); 302 if (dict.ContainsKey(depend)) 303 { 304 dict.Remove(depend); 305 //存回 306 MDictionary_SaveDict(dict); 307 } 308 } 309 #endregion 310 311 #endregion 312 }
老项目用到depend组,通过组控制组下面所有KEY/VALUE。升级Core改写代码过程中了解到EnyimMemcachedCore相关用法,所以基于博客园Memcached整理了此类。
据说EnyimMemcachedCore开发团队不推荐使用静态类,尽可能地避免使用静态类。
在使用Startup.cs中依赖注入时碰到缓存写入失败,暂未找到原因,以下是我的操作步骤,有清楚的园友请留言告知,谢谢。
第一步:配置文件
"enyimMemcached": { "Servers": [ { "Address": "127.0.0.1", "Port": 11211 } ] }
第二步:ConfigureServices配置AddEnyimMemcached
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); //memcachedcore1 services.AddEnyimMemcached(options => Configuration.GetSection("enyimMemcached").Bind(options)); }
第三步:Configure方法中使用
app.UseEnyimMemcached();//memcachedcore2
第四步:MVC模式下HomeController测试写入/读取
private IMemcachedClient _memcachedClient;//调用memcachedcore3 public HomeController(IMemcachedClient memcachedClient) { _memcachedClient = memcachedClient;//赋值memcachedcore4 } public IActionResult Index() { #region --测试memcachedcore-- MemcachedHelper.Set("memcached", "memcached-core", "memcachedcore" + DateTime.Now, 60); string mh = MemcachedHelper.Get("memcached-core").ToString(); ViewData["mhelper"] = mh; //这种方式暂未找到合适赋值,待研究,赋值赋不上。 //删/增/取memcachedcore5 //var cacheKey = "memcachedcore"; ////_memcachedClient.Add(cacheKey, "memcachedcore" + DateTime.Now, 60);//此方法赋不上值 ////var result = _memcachedClient.Get(cacheKey); //_memcachedClient.Remove(cacheKey); //ViewData["memcachedcore"] = result.ToString(); #endregion }
UtilConf读取配置文件操作类
public class UtilConf { private static IConfiguration config; public static IConfiguration Configuration//加载配置文件 { get { if (config != null) return config; config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); return config; } set => config = value; } }
2017-12-08 补充
如果多台memcached服务器,服务器时间一定要调整一致。如果不一致就会出现存不上值或过期日期不准确。