zoukankan      html  css  js  c++  java
  • .net core redis 驱动推荐,为什么不使用 StackExchange.Redis

    前言

    本人从事 .netcore 转型已两年有余,对 .net core 颇有好感,这一切得益于优秀的语法、框架设计。

    2006年开始使用 .net 2.0,从 asp.net 到 winform 到 winservice 等等领域开发都些许涉猎。对.net和大多数同胞有着类似的感触,那是又爱又恨,波段大致是这样:

    2010年以前,坚信 .net framework 能一统江湖霸业,不料在此之后,国内使用 .net 各大型领军公司纷纷转型 java,在每次面试和技术口舌之战时总有低人一等的感觉,没有自信。默默的忧桑。。。

    于是在2015年底,本人开始接触 linux,学习并使用了第一个跨平台服务端 web 语言 nodejs + express 框架,在完成开发交付时,发现脚本有很多致命问题,最严重那就是维护成本。

    经历这一次的项目开发,对软件工程学以及静态语言优点有了更深的体会,在同事推荐和劝导之下,开始学习了 .net core 1.0,看到第一个demo时,发现框架设计与 expressjs 实在太像了,够开放。。我喜欢。。遂一直坚持学习与使用到今天。

    遇到的坑

    两年时间开发了10+个中大型项目,印象最深刻的是第一个上线项目,一直报 StatckExchange.Redis Timeout 的 bug,当时资料非常少,google 各种姿势都试了(ThreadPool.SetMinThreads),都没能解决问题,只能临时放弃使用 redis,改用内存存储。

    解决问题

    为了 .net core 能在团队其他新项目推行使用,必须填平所有坑。于是乎各种搜索与排查,

    ServiceStack.Redis 是商业版,免费版有限制;

    发现了 csredis,作者在 2014 年以后就没有更新了,它不支持 .net core,但是它的源码可读性很强非常干净,几乎无任何依赖,我做了一部分代码修改后就能正常使用了。

    隆重介绍

    nuget Install-Package CSRedisCore

    源码地址:https://github.com/2881099/csredis

    经过了两年的洗礼,同胞们大可放心使用。

    1、增加了 CSRedisClient 现实集群与连接池管理,和 RedisHelper 静态类快速上手

    //普通模式
    
    var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,poolsize=50,ssl=false,writeBuffer=10240,prefix=key前辍");
    
    //集群模式
    
    var csredis = new CSRedis.CSRedisClient(null,
      "127.0.0.1:6371,password=123,defaultDatabase=11,poolsize=10,ssl=false,writeBuffer=10240,prefix=key前辍", 
      "127.0.0.1:6372,password=123,defaultDatabase=12,poolsize=11,ssl=false,writeBuffer=10240,prefix=key前辍",
      "127.0.0.1:6373,password=123,defaultDatabase=13,poolsize=12,ssl=false,writeBuffer=10240,prefix=key前辍",
      "127.0.0.1:6374,password=123,defaultDatabase=14,poolsize=13,ssl=false,writeBuffer=10240,prefix=key前辍");
    //实现思路:根据key.GetHashCode() % 节点总数量,确定连向的节点
    //也可以自定义规则(第一个参数设置)
    
    //mvc分布式缓存注入 nuget Install-Package Caching.CSRedis
    
    //初始化 RedisHelper
    RedisHelper.Initialization(csredis,
      value => Newtonsoft.Json.JsonConvert.SerializeObject(value),
      deserialize: (data, type) => Newtonsoft.Json.JsonConvert.DeserializeObject(data, type));
    //注册mvc分布式缓存
    services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance));
    
    //提示:CSRedis.CSRedisClient 单例模式够用了,强烈建议使用 RedisHelper 静态类
    RedisHelper.Set("test1", "123123", 60);
    RedisHelper.Get("test1");
    //...函数名基本与 redis-cli 的命令相同
    

      

    2、订阅与发布

    //普通订阅
    RedisHelper.Subscribe(
      ("chan1", msg => Console.WriteLine(msg.Body)),
      ("chan2", msg => Console.WriteLine(msg.Body)));
    
    //模式订阅(通配符)
    RedisHelper.PSubscribe(new[] { "test*", "*test001", "test*002" }, msg => {
      Console.WriteLine($"PSUB   {msg.MessageId}:{msg.Body}    {msg.Pattern}: chan:{msg.Channel}");
    });
    //模式订阅已经解决的难题:
    //1、集群的节点匹配规则,导致通配符最大可能匹配全部节点,所以全部节点都要订阅
    //2、本组 "test*", "*test001", "test*002" 订阅全部节点时,需要解决同一条消息不可执行多次
    
    //发布,
    RedisHelper.Publish("chan1", "123123123");
    //无论是集群或普通模式,RedisHelper.Publish 都能正常通信
    

      

    3、缓存壳

    //不加缓存的时候,要从数据库查询
    var t1 = Test.Select.WhereId(1).ToOne();
    
    //一般的缓存代码,如不封装还挺繁琐的
    var cacheValue = RedisHelper.Get("test1");
    if (!string.IsNullOrEmpty(cacheValue)) {
    	try {
    		return JsonConvert.DeserializeObject(cacheValue);
    	} catch {
    		//出错时删除key
    		RedisHelper.Remove("test1");
    		throw;
    	}
    }
    var t1 = Test.Select.WhereId(1).ToOne();
    RedisHelper.Set("test1", JsonConvert.SerializeObject(t1), 10); //缓存10秒
    
    //使用缓存壳效果同上,以下示例使用 string 和 hash 缓存数据
    var t1 = RedisHelper.CacheShell("test1", 10, () => Test.Select.WhereId(1).ToOne());
    var t2 = RedisHelper.CacheShell("test", "1", 10, () => Test.Select.WhereId(1).ToOne());
    var t3 = RedisHelper.CacheShell("test", new [] { "1", "2" }, 10, notCacheFields => new [] {
      ("1", Test.Select.WhereId(1).ToOne()),
      ("2", Test.Select.WhereId(2).ToOne())
    });
    

     

  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/kellynic/p/9325816.html
Copyright © 2011-2022 走看看