前言
本人从事 .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())
- });
来源: https://www.cnblogs.com/kellynic/p/9325816.html