【BCVP更新】StackExchange.Redis 的异步开发方式

有哪些习惯

坚持

LESS IS MORE,SIMPLER IS BETTER THAN MORE

你一定会有很大的收获

各种小问题?

如果你之前用过Redis的话,肯定会使用过StackExchange.Redis,我之前很久就用过,在.netfw的时候,当时并发还比较小,没有什么问题,后来我就迁移到Blog.Core里了,但是有很多小伙伴,反馈高并发下,使用同步的方法会有问题,比如超时的问题,偶尔还会出现什么内存的问题,一直被很多网友所诟病。

一直说国内有一个组件很不错,这个大家自己去使用吧,我也不多说什么,但是我想着StackExchange.Redis既然是官方推荐的不会这么菜吧,果然官方给的方案是,用异步的方式写,会解决超时的问题。

那具体应该怎么写呢,我还没有来得及思考,正好这两天研究微软的微服务案例eShopOnContainers,我发现他就是用的StackExchange.Redis实现的购物车缓存的子服务逻辑,研究了下,迁移到Blog.Core项目中,当然我这里简单测试了下,并发下没有问题,大家还是可以自行测试,当然还是那句话,有问题了我会继续修改,如果还是不行,那自己就换其他的组件吧。

设计异步方案

这个比较简单的,设计思路和之前的是一样的,只不过有一点,连接调制器的注入方式我做了调整(ConnectionMultiplexer),之前用的是双if夹lock的方式,实现的单例,现在直接使用依赖注入AddSingleton的方式,更专业些,也没那么幺蛾子:

/// <summary>
/// Redis缓存 启动服务
/// </summary>
public static class RedisCacheSetup
{
    public static void AddRedisCacheSetup(this IServiceCollection services)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));


        services.AddTransient<IRedisBasketRepository, RedisBasketRepository>();
        services.AddSingleton<ConnectionMultiplexer>(sp =>
        {
            //获取连接字符串
            string redisConfiguration = Appsettings.app(new string[] { "AppSettings", "RedisCachingAOP", "ConnectionString" });
            var configuration = ConfigurationOptions.Parse(redisConfiguration, true);
            configuration.ResolveDns = true;
            return ConnectionMultiplexer.Connect(configuration);
        });
    }
}

这里是Redis依赖注入的扩展方法,需要在Startup里配置上,别忘记了:

services.AddRedisCacheSetup();

然后就是设计接口和实现类了,也很简单,接口和之前的一样,只不过都换成了异步:

 /// <summary>
 /// Redis缓存接口
 /// </summary>
 public interface IRedisBasketRepository
 {


     //获取 Reids 缓存值
     Task<string> GetValue(string key);


     //获取值,并序列化
     Task<TEntity> Get<TEntity>(string key);


     //保存
     Task Set(string key, object value, TimeSpan cacheTime);


     //判断是否存在
     Task<bool> Exist(string key);


     //移除某一个缓存值
     Task Remove(string key);


     //全部清除
     Task Clear();
 }

接口的名称我为了纪念eShop项目,保持一致了,虽然比较怪,自己酌情修改吧。

然后实现类也很简单,构造函数直接注入日志和连接调制器实例,不用写复杂的单例模式了:

 public class RedisBasketRepository : IRedisBasketRepository
 {
     private readonly ILogger<RedisBasketRepository> _logger;
     private readonly ConnectionMultiplexer _redis;
     private readonly IDatabase _database;


     public RedisBasketRepository(ILogger<RedisBasketRepository> logger, ConnectionMultiplexer redis)
     {
         _logger = logger;
         _redis = redis;
         _database = redis.GetDatabase();
     }


     private IServer GetServer()
     {
         var endpoint = _redis.GetEndPoints();
         return _redis.GetServer(endpoint.First());
     }


     public async Task Clear()
     {
         foreach (var endPoint in _redis.GetEndPoints())
         {
             var server = GetServer();
             foreach (var key in server.Keys())
             {
                 await _database.KeyDeleteAsync(key);
             }
         }
     }


     public async Task<bool> Exist(string key)
     {
         return await _database.KeyExistsAsync(key);
     }


     public async Task<string> GetValue(string key)
     {
         return await _database.StringGetAsync(key);
     }


     public async Task Remove(string key)
     {
         await _database.KeyDeleteAsync(key);
     }


     public async Task Set(string key, object value, TimeSpan cacheTime)
     {
         if (value != null)
         {
             //序列化,将object值生成RedisValue
            await _database.StringSetAsync(key, SerializeHelper.Serialize(value), cacheTime);
         }
     }


     public async Task<TEntity> Get<TEntity>(string key)
     {
         var value = await _database.StringGetAsync(key);
         if (value.HasValue)
         {
             //需要用的反序列化,将Redis存储的Byte[],进行反序列化
             return SerializeHelper.Deserialize<TEntity>(value);
         }
         else
         {
             return default(TEntity);
         }
     }
 }

相应的逻辑也很简单,我详细基本都能看得懂。

最后就是在BlogRedisCacheAOP.cs中,也要修改下,毕竟改成了异步,还是要注意的:

写到最后

九月马上就要到了,新的一年也快结束了,准备好迎接125天的2021年了么!希望新的一年,一起都好起来,大家也要趁着时间好好学学知识,因为我相信到时候肯定会有很多岗位,机会总是会留给有准备的人,相信我,相信你自己。

生活の艺术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值