redis分布式锁和消息队列

最近博主在看redis的时候发现了两种redis使用方式,与以前redis做为缓存不一样,利用的是redis可设置key的有效时间和redis的BRPOP命令。redis

分布式锁

因为目前一些编程语言,如PHP等,不能在内存中使用锁,或者如Java这样的,须要一下更为简单的锁校验的时候,redis分布式锁的使用就足够知足了。
redis的分布式锁其实就是基于setnx方法和redis对key可设置有效时间的功能来实现的。基本用法比较简单。编程

public boolean tryLock(String lock,long expireTime){ String expire = String.valueOf(System.currentTimeMillis() + expireTime + 1); Long result = jedis.setNx(lock,expire); if(result == 1L){ jedis.expire(lock, expireTime); return true; } //判断超时key可能未删掉 String currentValue = jedis.get(lock); if(Long.parseLong(currentValue) < System.currentTimeMillis()){ jedis.set(lock, expire); jedis.expire(lock, expireTime); return true; } return false; } //expire是key的值,这里是为了防止运行超时锁被其余线程拿走以后误删锁 public unlock(String lock,String expire){ String value = jedis.get(lock); if(value != null && value != expire && Long.parseLong(value) > System.currentTimeMillis()) jedis.del(lock); } 

这里就是我根据redis的机制写的加锁和解锁方法。如今redis不推荐使用setNx了,而是直接使用set命令set(lock, expire,"NX", expireTime,"EX"),能够直接包括了setNx和expire的做用。缓存

消息队列

消息队列主要应用在网络服务中异步任务的实现,redis能够充当消息队列实现生产者/消费者模型和订阅/发布模型。网络

生产者/消费者模型

生产者/消费者模型须要存在生产者和消费者两方,而在redis中队列的存储和获取能够做为消息队列被生产者和消费者使用,这里就不用Java代码写了,使用redis命令来讲明。
其实redis在其中作的仍是缓存的做用,LPUSH queue task,将task放到queue队列里面,这里稍微偏题一句,其实redis有lpush和rpush,意思就是从左边插入队列和从右边插入队列。这就是生产者的部分,将任务插入到指定队列中。
消费者的部分有点类似,就是使用BRPOP queue 10,固然这里的BRPOP也有对应的BLPOP,因为队列是按顺序取任务的,因此这边作的是左边插入,右边取出。这里须要注意的是,redis有BRPOP和RPOP,之因此用BRPOP的缘由是这个有一个等待,就是命令中的10,这是一个等待时间,以秒为单位,意思是若是队列中是空的,那么我先不返回,我等待10秒,若是期间有新的任务插入,那么我就取新的任务返回,仍是没有的话,返回空。
另外BRPOP还支持优先级,就是BRPOP queue:1 queue:2 queue:3 10,这个意思是顺序获取,若是queue:1没有取到任务,到queue:2去取,依次日后。异步

订阅/发布模型

订阅/发布模型简单来讲就是由发布者向全部订阅者发送任务,任何订阅者均可以获取任务,这里redis的实现就是使用订阅命令。
发布者可使用publish channel task来发布相关的任务,而订阅者则是使用subscribe channel,这是一个监听命令,redis会一直监听这个channel,若是发布者发布新的任务,监听命令会返回任务,直到订阅者主动退出监听。可是redis也为这个设置超时,保证监听的有效性,默认若是60s内没收到消息就异常退出,固然这个可配置。编程语言