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

分布式锁

由于目前一些编程语言,如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内没收到消息就异常退出,当然这个可配置。

redis分布式锁和消息队列的更多相关文章

  1. 循序渐进 Redis 分布式锁(以及何时不用它)

    场景 假设我们有个批处理服务,实现逻辑大致是这样的: 用户在管理后台向批处理服务投递任务: 批处理服务将该任务写入数据库,立即返回: 批处理服务有启动单独线程定时从数据库获取一批未处理(或处理失败)的 ...

  2. Lua脚本在redis分布式锁场景的运用

    目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...

  3. Redlock:Redis分布式锁最牛逼的实现

    普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...

  4. redis分布式锁小试

    一.场景 项目A监听mq中的其他项目的部署消息(包括push_seq, status, environment,timestamp等),然后将部署消息同步到数据库中(项目X在对应环境[environm ...

  5. Redis分布式锁的实现

    前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...

  6. Redis分布式锁实现简单秒杀功能

    这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...

  7. Redis分布式锁实战

    什么是分布式锁 在单机部署的情况下,要想保证特定业务在顺序执行,通过JDK提供的synchronized关键字.Semaphore.ReentrantLock,或者我们也可以基于AQS定制化锁.单机部 ...

  8. 死磕 java同步系列之redis分布式锁进化史

    问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...

  9. 自己写了个简单的redis分布式锁【我】

    自己写了个简单的redis分布式锁 [注意:此锁需要在每次使用前都创建对象,也就是要在线程内每次都创建对象后使用] package redis; import java.util.Collection ...

随机推荐

  1. nginx反向代理cas-server之2:生成证书,centOS下使用openssl生成CA证书(根证书、server证书、client证书)

    前些天搭好了cas系统,这几天一致再搞nginx和cas的反向代理,一直不成功,但是走http还是测试通过的,最终确定是ssl认证证书这一块的问题,原本我在cas服务端里的tomcat已经配置了证书, ...

  2. js事件循环

    之前有看过一些事件循环的博客,不过一阵子没看就发现自己忘光了,所以决定来自己写一个博客总结下! 首先,我们来解释下事件循环是个什么东西: 就我们所知,浏览器的js是单线程的,也就是说,在同一时刻,最多 ...

  3. Spring学习(3)---Spring设值注入和构造注入

    (一)设值注入就是指要被注入的类中定义有一个setter()方法,并在参数中定义需要注入的对象.简单的看个例子. 建一个User类: package com.ioc; public class Use ...

  4. 通过JSP+servlet实现文件上传功能

    在TCP/IP中,最早出现的文件上传机制是FTP.它将文件由客户端到服务器的标准机制. 但是在JSP中不能使用FTP来上传文件,这是有JSP的运行机制所决定的. 通过为表单元素设置Method=&qu ...

  5. js获取网页请求类型是http还是https

    代码如下,即可判断 var ishttps = 'https:' == document.location.protocol ? true : false; if(ishttps) { alert(& ...

  6. Bash的命令替换

    命令替换:将命令替换为命令的输出,所有的shell支持使用反引号的方法进行命令替换.Bash支持两种形式:$(command) 和`command`命令替换是可以嵌套的,如果使用反引号的形式,在内部反 ...

  7. [0] C# 扩展方法(Extension Method)

    有时有这样的情况,有一个类,你不能修改它,但你又想对它扩展(添加一个方法),这个时候就可以用到扩展方法了.请看下面的例子: using System;using System.Collections. ...

  8. react实现双向绑定

    双向绑定功能是在项目中比较常见的一个需求,传统的js实现方式是添加监听函数的方式,Vue框架实现很简单,因为它本身就是基于双向绑定实现的,接下来我将讲解一下如何使用react实现双向绑定的功能是 首先 ...

  9. DataFrame操作方式

    DataFrame/DataSet 操作 Databricks 不止一次提到过希望未来在编写 Spark 应用程序过程中,对于结构化/半结构化数据,使用 Datasets(DataFrame 的扩展) ...

  10. Spring MVC 项目搭建 -5- spring security 使用数据库进行验证

    Spring MVC 项目搭建 -5- spring security 使用数据库进行验证 1.创建数据表格(这里使用的是mysql) CREATE TABLE security_role ( id ...