2019独角兽企业重金招聘Python工程师标准>>>

分布式系统经常要遇到定时任务执行的问题,不能重复执行,但很多时候又不能统一到一个微服务里面,因为这样就失去了微服务的意义。由于我的系统只有寥寥几个定时任务,而且都是按天执行的,我就弄了这么个小东西来控制分布式定时任务。

我使用的redis分布式锁来控制分布式定时任务的方式,实际上适用于定时任务较少的情况,而且不适用于瞬时反复执行的定时任务。这种情况下,如果加上分布式定时任务框架,如Elastic-Job这种,显然就很重了,所以这是一个极轻量级的方式。这种方式显然很难支持作业分片、失效转移、重新触发执行以及执行过程中服务挂掉之后的重新执行。所以使用这种方式要慎重,如果系统存在后续定时任务大规模扩展、定时任务需要分片或者有瞬时反复执行的定时任务等情况,则这种简单的方式就不适用了。

原理其实很简单,各个微服务系统同时向redis申请加锁,由于redis是单线程的,所以只能有一个加锁成功,然后后面的全部得不到锁。得到锁的执行定时任务,得不到的,就放弃执行定时任务。

为啥要用lua脚本呢?因为好用啊,亲,操作的原子性能得到保证。

小demo:

@Test
public void testgg(){try{jedisCluster.del("schedule:lock:sss");String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());for (int i=0;i<30;i++){Thread thread = new Thread(new Runnable() {@Overridepublic void run() {//lua脚本String luaScript = "local vals = redis.call('setnx', KEYS[1],'lock') if  vals > 0 then redis.call('expire',KEYS[1], 1) end  if  vals > 0  then return 1 end return 0";//执行lua脚本Object lockVal = jedisOperationUtils.executeLuaScript(luaScript,1, "schedule:lock:sss");System.out.println(lockVal.toString()+"  "+Thread.currentThread().getName());if(lockVal!=null && Integer.valueOf(lockVal.toString())>0){//得到锁,执行定时任务的内容}}});thread.start();Thread.currentThread().sleep(100);}try{Thread.currentThread().sleep(10000);}catch (Exception e){System.out.println("ooooooooooooooooooooooooooooo");e.printStackTrace();}}catch (Exception e){System.out.println("IIIIIIIIIIIIIII");e.printStackTrace();}
}

这个例子就大概表达了整个思路的意思。其实相当简单。

里面的

jedisOperationUtils.executeLuaScript(......)

方法是封装的,我不需要ARGV[],所以就没封装进去。

/*** lua脚本执行* @param luaScript* @param keyCount* @param keys* @return*/
public Object executeLuaScript(String luaScript,int keyCount,String ... keys){Object object = null;try{object = jedisCluster.eval(luaScript,keyCount,keys);if(object == null){return null;}}catch(Exception e){log.error("执行redislua脚本失败",e);return null;}return object;
}

OVER

转载于:https://my.oschina.net/forever9999/blog/2245321

使用redis分布式锁+lua脚本实现分布式定时任务控制demo相关推荐

  1. 基于 Redis + Lua 脚本实现分布式锁,确保操作的原子性

    为了保证数据的争用安全,通常要采用锁机制控制. 如果是单应用部署,直接通过synchronized关键字修改方法,就能解决,但是如果是分布式的部署 该方法就不能解决这个问题啦,此时就引出了一个分布式锁 ...

  2. 分布式锁系列--04关于分布式锁的选型分析02-Redlock的实现原理

    欢迎关注公众号:java4all 上一文分布式锁系列–03关于分布式锁的选型分析01中,我们看到了单节点的redis分布式锁在failover时产生了无法解决的安全问题,因此,Redis的作者anti ...

  3. 什么是分布式锁?几种分布式锁分别是怎么实现的?

    一.什么是分布式锁: 1.什么是分布式锁: 分布式锁,即分布式系统中的锁.在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题.与单体应用不同 ...

  4. 【分布式锁】三种分布式锁的实现【原创】

    分布式锁 0x00 概述 0x02 实现方式 0x03 分布式锁:基于数据库 1. 实现思想 A. 悲观锁(排他锁) B. 乐观锁 2. 优缺点 0x04 分布式锁:基于Zookeeper 1. 实现 ...

  5. 深入理解redis中的lua脚本

    本文来说下redis中的lua脚本 文章目录 概述 Lua简介 使用Lua脚本的好处 Redis+Lua实现限流 本文小结 概述 今天讲一些redis和lua脚本的相关的东西,lua这个脚本是一个好东 ...

  6. 【SpringBoot框架篇】31.基于分布式锁或xxx-job实现分布式任务调度

    文章目录 1.简介 2.分布式锁实现 2.1.引用依赖 2.2.定义分布式锁注解 2.3.配置切入点和获取锁释放锁逻辑 2.4.测试任务 3.使用分布式任务调度平台xxx-job 3.1.下载源码并运 ...

  7. Redis中的Lua 脚本

    Lua/ˈluə/是一种轻量级脚本语言,它是用C 语言编写的,跟数据的存储过程有点类似.使用Lua 脚本来执行Redis 命令的好处: 1.一次发送多个命令,减少网络开销. 2.Redis 会将整个脚 ...

  8. Redis中使用Lua脚本(续)- Linux下Lua-cjson开源库的安装和使用

    Redis中使用Lua脚本(续)- Lua-cjson开源库的安装和使用 问题 原因 解决方案 在Redis的lua脚本编写中,我们可能会用到json的序列化和反序列化. Json序列化: -- Re ...

  9. Redis中的Lua脚本怎么玩

    Redis中的Lua脚本怎么玩 Lua是一门强大.快速.轻量的嵌入式脚本语言,我们日常开发中接触的最多的还是Redis为保证原子性使用Lua执行多命令的一种方法,那么现在先来熟悉Lua基本用法. Lu ...

最新文章

  1. 习题3-3 数数字(Digit Counting , ACM/ICPC Danang 2007, UVa1225)
  2. 30行代码消费腾讯人工智能开放平台提供的自然语言处理API
  3. div+css+theme
  4. 1.VMware Workstation 12 中安装CentOS
  5. word2vec实例详解python_Python实现word2Vec model过程解析
  6. 优化gradle下载引用jar速度慢或者出错的问题
  7. 足球预测_预测足球热
  8. LeetCode MySQL 1322. 广告效果
  9. 如果面试官问你:Redis 内存满了怎么办?
  10. webpack 合并压缩_webpack 打包压缩js和css的方法示例
  11. 敏捷20周年:一场失败的起义
  12. 8.软件架构设计:大型网站技术架构与业务架构融合之道 --- 高并发问题
  13. Android PopupWindow的简单说明
  14. uni.navigateTo页面跳转时传对象参数
  15. 1MB,1GB,1TB等于多少字节或比特?(理解B与b的区别)
  16. 小程序使用云开发,拍照获取银行卡卡号
  17. 虚拟服务器的克隆,怎么克隆远程服务器上的虚拟机
  18. 可执行 jar 和普通 jar 区别
  19. M1芯片实现Kail虚拟机(无Parallels)
  20. 38、EST序列拼接流程

热门文章

  1. JavaScript学习之Object(下)this
  2. python中依次输出字符_Python如何输出某关键字符并输出完整字符串
  3. mysql 空位补0_MySQL-13(表的创建、数值类型整型、float/decimal、ZEROFILL、BIT(M))
  4. java restful开发规范_restful api 开发规范
  5. abap中读取excel中不同的sheet数据_Python 如何将数据写入Excel的不同或同一个工作簿中...
  6. Alibaba Druid 源码阅读(五)数据库连接池 连接关闭探索
  7. android屏幕亮度测试,屏幕亮度与可视角度测试_手机Android频道-中关村在线
  8. c语言如何制作多线程序,c语言中如何创建多线程。最好有一个例子,谢谢!!...
  9. Java文件如何用qq邮箱发送_java中怎么发送复杂的邮件?在QQ邮箱中怎么操作?
  10. STM32编译环境、建立工程模板以及程序下载