范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

干掉RedisHelper,请这样用分布式缓存

  前言
  我们在项目中使用Redis时通常是写一个单例模式的RedisHelper静态类,暴露一些常用的Get、Set等操作,在需要使用地方直接RedisHelper.StringGet(xx,xx)就可以了,这样虽然简单粗暴地满足我们对Redis的所有操作需要,但是这在Asp.Net Core的项目显得不是那么优雅了。首先你的RedisHelper静态类无法使用Asp.Net Core容器,又如何优雅的通过依赖注入获取IConfiguration中的配置项呢?既然我们使用Asp.Net Core这么优秀的框架,最佳实践当然就是遵循官方建议的开发规范优雅的编写代码。 IDistributedCache
  若要使用 SQL Server 分布式缓存,请添加对 Microsoft.Extensions.Caching.SqlServer 包的包引用。
  若要使用 Redis 分布式缓存,请添加对 Microsoft.Extensions.Caching.StackExchangeRedis 包的包引用。
  若要使用 NCache 分布式缓存,请添加对 NCache.Microsoft.Extensions.Caching.OpenSource 包的包引用。
  无论选择哪种实现,应用都将使用 IDistributedCache 接口与缓存进行交互。
  来看下IDistributedCache这个接口的定义 namespace Microsoft.Extensions.Caching.Distributed;  ///  /// Represents a distributed cache of serialized values. ///  public interface IDistributedCache {     ///      /// Gets a value with the given key.     ///      byte[]? Get(string key);      ///      /// Gets a value with the given key.     ///      Task GetAsync(string key, CancellationToken token = default(CancellationToken));      void Set(string key, byte[] value, DistributedCacheEntryOptions options);      ///      /// Sets the value with the given key.     ///      Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken));      ///      /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).     ///      void Refresh(string key);      ///      /// Refreshes a value in the cache based on its key, resetting its sliding expiration timeout (if any).     ///      Task RefreshAsync(string key, CancellationToken token = default(CancellationToken));      ///      /// Removes the value with the given key.     ///      void Remove(string key);      ///      /// Removes the value with the given key.     ///      Task RemoveAsync(string key, CancellationToken token = default(CancellationToken)); }
  IDistributedCache 接口提供以下方法来处理分布式缓存实现中的项: Get、GetAsync:如果在缓存中找到,则接受字符串键并以 byte[] 数组的形式检索缓存项。 Set、SetAsync:使用字符串键将项(作为 byte[] 数组)添加到缓存。 Refresh、RefreshAsync:根据键刷新缓存中的项,重置其可调到期超时(如果有)。 Remove、RemoveAsync:根据字符串键删除缓存项。 干掉RedisHelper
  官方不仅提出了如何最佳实践分布式缓存的使用,还提供了基本的实现库给我们直接用,比如我们在项目中用Redis为我们提供缓存服务: 添加引用Microsoft.Extensions.Caching.StackExchangeRedis 注册容器AddStackExchangeRedisCache,并配置参数  builder.Services.AddStackExchangeRedisCache(options =>      {          options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");          options.InstanceName = "SampleInstance";      }); 在需要使用Redis的地方通过构造函数注入IDistributedCache实例调用即可
  这样就可以优雅的使用Redis了,更加符合Asp.Net Core的设计风格,养成通过容器注入的方式来调用我们的各种服务,而不是全局使用RedisHelper静态类,通过IOC的方式,结合面向接口开发,能方便的替换我们的实现类,统一由容器提供对象的创建,这种控制反转带来的好处只可意会不可言传,这里就不赘述了。 AddStackExchangeRedisCache到底干了什么
  上面已经知道如何优雅的使用我们的Redis了,但是不看下源码就不知道底层实现,总是心里不踏实的。
  源码比较好理解的,因为这个Nuget包的源码也就四个类,而上面注册容器的逻辑也比较简单
  AddStackExchangeRedisCache主要干的活 // 1.启用Options以使用IOptions services.AddOptions(); // 2.注入配置自定义配置,可以通过IOptions注入到需要使用该配置的地方 services.Configure(setupAction); // 3.注入一个单例IDistributedCache的实现类RedisCache services.Add(ServiceDescriptor.Singleton());
  所以我们在需要用Redis的地方通过构造函数注入IDistributedCache,而它对应的实现就是RedisCache,那看下它的源码。
  这里就不细看所有的实现了,重点只需要知道它继承了IDistributedCache就行了,通过AddStackExchangeRedisCache传入的ConnectionString,实现IDistributedCache的Get、Set、Refresh、Remove四个核心的方法,我相信这难不倒你,而它也就是干了这么多事情,只不过它的实现有点巧妙。
  通过LUA脚本和HSET数据结构实现,HashKey是我们传入的InstanceName+key,做了一层包装。
  源码中还有需要注意的就是,我们要保证Redis连接对象IConnectionMultiplexer的单例,不能重复创建多个实例,这个想必在RedisHelper中也是要保证的,而且是通过lock来实现的。
  然而微软不是那么用的,玩了个花样,注意下面的_connectionLock.Wait();: private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(initialCount: 1, maxCount: 1);  [MemberNotNull(nameof(_cache), nameof(_connection))] private void Connect() {     CheckDisposed();     if (_cache != null)     {         Debug.Assert(_connection != null);         return;     }      _connectionLock.Wait();     try     {         if (_cache == null)         {             if (_options.ConnectionMultiplexerFactory == null)             {                 if (_options.ConfigurationOptions is not null)                 {                     _connection = ConnectionMultiplexer.Connect(_options.ConfigurationOptions);                 }                 else                 {                     _connection = ConnectionMultiplexer.Connect(_options.Configuration);                 }             }             else             {                 _connection = _options.ConnectionMultiplexerFactory().GetAwaiter().GetResult();             }              PrepareConnection();             _cache = _connection.GetDatabase();         }     }     finally     {         _connectionLock.Release();     }      Debug.Assert(_connection != null); }
  通过SemaphoreSlim限制同一时间只能有一个线程能访问_connectionLock.Wait();后面的代码。
  学到装逼技巧+1 思考
  IDistributedCache只有四个操作:Get、Set、Refresh、Remove,我们表示很希望跟着官方走,但这个接口过于简单,不能满足我的其他需求咋办?
  比如我们需要调用 StackExchange.Redis封装的LockTake,LockRelease来实现分布式锁的功能,那该怎么通过注入IDistributedCache调用?
  我们可以理解官方上面是给我们做了示范,我们完全可以自己定义一个接口,比如: public interface IDistributedCachePlus : IDistributedCache {     bool LockRelease(string key, byte[] value);      bool LockTake(string key, byte[] value, TimeSpan expiry); }
  继承IDistributedCache,对其接口进行增强,然后自己实现实现AddStackExchangeRedisCache的逻辑,我们不用官方给的实现,但是我们山寨官方的思路,实现任意标准的接口,满足我们业务。 services.Add(ServiceDescriptor.Singleton());
  在需要使用缓存的地方通过构造函数注入IDistributedCachePlus。 总结
  官方提供的IDistributedCache标准及其实现类库,能方便的实现我们对缓存的简单的需求,通过遵循官方的建议,我们干掉了RedisHelper,优雅的实现了分布式Redis缓存的使用,你觉得这样做是不是很优雅呢?
  原文链接:https://www.cnblogs.com/springhgui/p/16290803.html

最奇葩的三款月饼,老坛酸菜加老干妈,这酸爽!根本忘不了!第3名巧克力香辣牛肉月饼外表是一层巧克力,里面裹着的是麻辣牛肉馅,甜甜的巧克力与麻辣牛肉馅相结合,这口感简直就是外焦里嫩的真实写照啊!据说该月饼刚一上市,就吸引了不少人购买!第2名实在太太太漂亮了!世界上超美的三个女孩,真人版的芭比娃娃一双清澈如大海的湛蓝色眼眸,一副和芭比娃娃一样精致的脸,这颜值简直高到爆表,世界公认三个最美的女孩,你都知道谁?321发兔来公布答案!第三名JareIjalana这个小女孩来自尼日生孩子最难的三种动物,有些被困在产道中窒息而亡听说动物也难产?没错,有榜单哦第三名豪猪这家伙身上的尖刺是它们自卫的强大武器,但小豪猪刚生下来时身上的尖刺像羽毛一样柔软,倒也不会伤到雌性豪猪,万一生产不顺,幼儿的羽毛留在母亲体内29岁美女与大猩猩结婚,还一度扬言要与大猩猩生孩子跨越种族的爱情,美女与大猩猩结婚!啾咪啾咪!和发兔去看看是的,你没听错,美国29岁的安娜对大猩猩产生了爱。对,爱情的那种。更扯淡的是,一人一猩还常在朋友圈狂撒狗粮,家人知道后差点没如何在手机上登陆两个微信,如何设置手机应用分身功能大家平时使用手机的时候,手机上面只能登陆一个微信。那有没有一种办法,可以在手机上面登录两个微信呢,或者是两个QQ呢。答案是有的,那具体怎样进行设置呢。如何在手机上登录两个微信,如何超级贵的三款运动鞋,第一名灵感来自电影,可以自动系鞋带第3名AirYeezy2RedOctober价格约合人民币2万元左右,是Yeezy系列的巅峰之作,虽然这款鞋不是最贵的,但绝对是被炒的最火热的一款鞋。由于其特殊性质,导致目前已经绝用真诚赢得真诚,用服务温暖客户专访齐星地产高级置业经理杨生2021年,对房产行业而言是拥抱变化的一年,是颠覆现状的一年,也是创新求变的一年。在房产市场发展格局快速转变的大环境下,作为国内领先的房产信息服务平台,58同城致力于发挥数据技术和汽车空调冬天制热为何大部分用户选择外循环进风?当我们在冬天开车时都会打开汽车空调来制热,一般来说,当车辆在行驶过程中,车内的温度应该比车外的温度高,选择内循环进风模式的制热效率要好,为什么很多用户都会选择外循环进风模式?我们选继刀片电池DMi之后,比亚迪再放大招e平台3。0,用户闭眼买新能源汽车领域,比亚迪的火有目共睹。最新数据显示,比亚迪新能源乘用车8月销量高达60508辆,再度刷新中国纪录。2020年,比亚迪正式推出具有划时代意义的刀片电池,成功挑战了极端强采用吉利全新家族式设计远景X6PRO或本月下旬上市,内饰年轻化日前,吉利汽车公布了远景X6PRO的高清官图。据悉,新车采用吉利全新家族式设计,整体更显动感和年轻。同时,新车有望在9月下旬正式上市。新车采用能量音弦前格栅设计,与熏黑Logo完美大众探影对比本田XRV谁才是年轻消费者的终结者?对于年轻消费者来说,配置丰富的小型SUV成为了不少人的首选。这其中,合资品牌产品则凭借着较为出众的产品力,占据了一席之地。今天,我们就带来大众探影和本田XRV,看看谁才是小型SUV
印度居然扣押小米几十亿海外资产,如果印度真禁小米,有影响吗?印度居然扣押小米几十亿海外资产印度为什么封杀小米不是这样的。小米没有全部在印度被下架。红米系列使用高通处理器的,已经恢复销售,当然要缴纳保证金。各国各地知识产权保护的要求不一样,因小米夺得第一,国产占据七成,为什么只有华为在印度水土不服?小米手机在印度扣了48亿了。自己慢慢想是怎么回事了。黑小米一个建议,谈小米时不要碰瓷华为,小米都世界数一数二了,再谈小米应该同三星和苹果比较。因为华为在印度没海军!因为在印度赚不到Truist将亚马逊(AMZN。US)目标价从4000美元下调至3500美元Truist将亚马逊(AMZN。US)目标价从4000美元下调至3500美元。亚马逊(AMZN。US)公司简介亚马逊公司从事提供在线零售购物服务。它的工作通过以下业务北美,国际和亚新能源汽车充电时可以锁车吗新能源汽车充电时可以锁车,有一部分车型即便在充电状态下,只要按下启动按钮,就能正常启动,而且还能挂档行驶。这种设计,明显是不安全的,很容易使消费者因忘记车辆处于充电状态,而扯坏充电比惨大会蔚来交付5074辆,理想直接腰斩此前,小鹏汽车创始人何小鹏曾表示如果上海和周边的供应链企业还无法找到动态复工复产的方式,五月份可能中国所有的整车厂都要停工停产了,但还好的是,在4月份末,上海部分企业已经开启有序复A股上市公司豪言哈福毕业生在我们公司也只能做实习生哈佛毕业生,来我们公司,也只能做实习生,录取率比哈佛还低!这是国内一家公司的招聘广告,这家口气很大的公司名字叫格灵深瞳。国内人工智能第一股!2012年,真格基金的创始人徐小平去了趟C中STL常见问题汇总,越来越熟悉STL底层原理和应用(2)STL中迭代器什么时候会失效?对于序列容器vector,deque来说,使用erase后,后边的每个元素的迭代器都会失效,后边每个元素都往前移动一位,erase返回下一个有效的迭代买30万的比亚迪,50万的蔚来就是缴纳爱国税?买国产车就是缴纳爱国税,这个言论最近在很多合资品牌海外品牌进口品牌车主嘴里面蹦出来非常刺耳朵,因为最近以造车新势力为代表的蔚来极氪理想岚图比亚迪华为问界等高端车型动辄卖到了3060Linux启动时间优化实战,2。41秒启动应用劳动节,更个文吧,祝大家都劳有所获。今天看了一个关于启动优化的讲座,简单总结一下。本文的目标是尝试一些比较简单有效的方法,并不会覆盖所有的优化技巧。感兴趣的伙伴可以关注我视频号,后有颜有实力!vivoX80Pro尽显旗舰优势日前,vivoX80系列正式迎来了开售,受到了许多消费者的热捧。这款被官方称之为第二代双芯旗舰的产品,不仅搭载了强悍双芯,而且还加持了强大的影像系统,并在外观屏幕等多个方面有着可圈2K直屏5500mAh67W,现已跌至2749元,还有12256GB大内存根据四月份某东自营手机销量排行来看,大环境的恶略情况对于智能手机销量造成的影响也是不小,包括iPhone13在内的所有机型均受到了影响,整体销量出现了较为明显的下滑趋势,而在这个时