Redis实现消息队列

记录Redis实现消息队列遇到的一些问题。

首先说为什么用Redis实现消息队列呢?主要是公司的一些业务不是很依赖与MQ,所以没用专门的MQ工具。本次用Reids实现消息队列主要是Redis上手容易,不需要复杂的配置,
其次也是想着解耦和异步。
据了解Redis支持两种方式实现MQ:第一种就是基于List lpush-brpop(rpush-blpop)实现的;
也可以使用rpush和lpush操作入队列,lpop和rpop操作出队列,但是当列表为空时,lpop和rpop会一直空轮询,消耗资源。所以有了上面的改进实现。
brpop和blpop阻塞读,在队列没有消息的时候阻塞,一旦消息来了就醒了。
但是据说阻塞读也有一个问题就是如果阻塞的时间长了,Redis客户端主动断开连接,这个时候阻塞读会抛出异常,所以一般来讲要处理异常并重试。
开发中尝试用这种方式实现MQ发现,这中方式也只能在客户端命令行的方式玩玩,因为出列同入列一样需要不断的调用,试想这一定不是我们要的。
如果非要这么用,那只能轮询了。
第二种基于订阅/发布;publish channel msg/subscribe channel可以一次广播多信道订阅(一个消息可以发布到多个消费者),操作的过程也发现一些缺点就是如果客户端不存在时消息一旦发布就会丢失且不能寻回。该种方式一般用于即时通讯。
开发中遇到的问题是subscribe也是阻塞的,subscribe代码段必须异步执行并且为了不丢失消息要及早执行。
所以我借鉴网上的把订阅的代码单独封装然后通过Thread类run方法执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
StackExchange.Redis,这是redis 的.net客户端之一。Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务。目前有不少人在使用    ServiceStack.Redis这个.net客户端,但是这个的最新版本目前已经变成了商业软件。对于    ServiceStack.Redis这种行为,我们没有什么好说的,留给我们的选择是使用低版本的开源版本或者转向其他的客户端。要说到StackExchange.Redis,就不得不说它和BookSleeve的关系。BookSleeve已经是比较完善的redis sdk,但是为什么 BookSleeve 的作者要重新写一个redis 的客户端sdk呢? 有兴趣的同学可以看这里    why i wrote another redis client归纳起来其实就一句话:觉得不爽就推倒重来。StackExchange.Redis 安装直接命令或者手动NuGet。 PM> Install-Package StackExchange.Redis 如果需要强签名的版本走下面的命令,当然作者对于强签名的事也是充满了    怨念  PM> Install-Package StackExchange.Redis.StrongName ConnectionMultiplexerConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,你不要在每个操作中不停的创建该对象的实例,所以使用单例来创建和存放这个对象是必须的。public static ConnectionMultiplexer Manager     {         get         {             if (_redis == null)             {                 lock (_locker)                 {                     if (_redis != null) return _redis;                     _redis = GetManager();                     return _redis;                 }             }             return _redis;         }     }     private static ConnectionMultiplexer GetManager(string connectionString = null)     {         if (string.IsNullOrEmpty(connectionString))         {             connectionString = GetDefaultConnectionString();         }         return ConnectionMultiplexer.Connect(connectionString);     }虽然ConnectionMultiplexer是实现了IDisposable接口的,但是我们基于重用的考虑,一般不需要去释放它。当作内存数据库使用IDatabase db = redis.GetDatabase(); 这里的GetDatabase() 返回的db对象是很轻量级别的,不需要被缓存起来,每次用每次拿即可。IDatabase 的所有方法都有同步和异步的实现。其中的异步实现都是可以await的。一些基础的操作的封装。public bool Remove(string key)     {         key = MergeKey(key);         var db = RedisManager.Manager.GetDatabase(Database);         return db.KeyDelete(key);     }     public string Get(string key)     {         key = this.MergeKey(key);         var db = RedisManager.Manager.GetDatabase(Database);         return db.StringGet(key);     }     public bool Set(string key, string value, int expireMinutes = 0)    

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值