先说一下我们的系统,

在65和66上分别部署有weblogic节点,共计四个,在项目中我们的定时器会隔一段时间就从其它的五个系统中取数据,这时就出现了问题,本来取一次数据就可以的,现在重复执行了三次,同时还造成了对方服务器的压力。

现在说一下我们项目怎么解决的这个问题:

1、首先想到的是在定时执行任务这个文件中添加ip地址,固定成某一台能执行,但我们一台服务器上有两个节点,方案不可行。

2、后来想到使用redis来保存一个状态位,是1表示可以执行,0表示不可以执行,但要是一个节点get到的是1,在它设置此status为0的时候,另一个节点提前一点点get到的也是1,这个时候这两个节点就都会执行,随后想到可不可以使用redis的事务加watch关键字,细想之后redis的事务是一组命名打包执行,中间不再执行其它操作,也实现不了。

3、既然redis的事务不可以,那数据库的应该可以吧。从而最终找到了现在的解决方案。

能解决的问题:

1、多个节点只有一个节点执行任务

2、即使某个正在执行的节点挂掉了,没有来的及修改状态位,也不影响定时器的执行。

下面是数据库表的设计:

这个表是用来表示当前查询的任务是否可以执行,通过type字段可以将多个不同类型的定时器进行区分,从而实现表的共用。

此表中的status字段表示是否可以执行定时任务。

Datetime字段用来记录当前任务的执行时间。

Intervallen这个字段是我们规定一段时间间隔。

代码示例如下:

------------------------------------------

这个是具体的查询是否可以执行任务的逻辑。

下面是具体的sql

这里的for update很重要。

下面针对上面的步骤说明一下:

1、当定时器执行的时候会执行running = sysScheduleStatusService.getAndSetScheduleStatus(parameter);

这个方法,running表示是否可以执行,true表示可以执行。

2、在这个方法中,会先执行SysScheduleStatus scheduleStatus = sysScheduleStatusDao.getScheduleStatus(parameter);这个方法,此方法会调用id为getScheduleStatus的sql语句,这个语句中的for update 关键字会对查询出来的记录加锁。即:

对这一条记录加锁(type为1表示某个类型的定时器)。
然后根据取出来的数据判断status是否为1,为1表示可以执行此定时器,随即调用update方法,将数据库的此字段改为0(不可以执行),提交事务,返回true。由于for update的存在,当某个线程执行这个查询语句的时候,已经对此条记录加锁,别的线程再去查询的时候就会处于等待状态,直到这个线程的事务提交,然后才可以查询,此时查询到的status为0,不可以执行,返回false。
在定时器方法的最后我们要更新表的status为1,以便下一次能顺利执行。这个update的方法我们一定要放到finally中,否则出现异常就有可能这个状态位一直为0了(其实为0也可以解决的);
我们通过status是否为1来判断是否可以执行,但要是节点在执行定时器的时候突然宕机或者其它原因,没有及时的将status设置成1,这个时候我们的定时器就永远走不了了。在这里就使用到了datetime字段和intervallen字段了。
逻辑:当status为0时,我们继续向下走,获取当前时间,当当前时间大于datetime+intervallen时我们就认为某个执行定时器的节点不是宕机就是出现其它异常导致未能及时的将status字段设置成1。这时我们照样返回true,同时更新一下对应type的status和datetime字段。这样即使节点挂掉,也不影响下一次定时任务的执行(由其它节点执行)。
在我这个代码里面我是直接在数据库里面进行了判断,isovertime表示是否超时,为1表示超时我们返回true,执行任务。(这样考虑是因为我们用sysdate来和datetime比较是比较好的,如果我们拿到java代码里面的话,有可能java运行的服务器的时间和数据库的时间不同步)
 
优化:由于我们的定时任务执行的时间比较长,其实还可以将查询出来的list分成三四个list,然后让spring的线程池threadPoolTaskExecutor来执行,从而减少执行时间。
 

要说明一点:

Service 中的这个getAndSetScheduleStatus()方法一定要开启事务。我在做这个的时候发现我们项目中的事务配置的不太对,从而这个方法没有开启事务,当多个节点执行时就出现因为for update而一直等待的情况。下图是事务的配置:


https://zhidao.baidu.com/question/510837808.html
 
 

多台或者集群环境下如何保证spring定时器只执行一个的更多相关文章

  1. Ubuntu14(64位) 集群环境下安装Hadoop2.4

    经过前边的积累,今天最终实现了集群环境下部署Hadoop.并成功执行了官方的样例. 工作例如以下: 两台机器: NameNode:上网小本,3G内存.机器名:YP-X100e,IP:192.168.1 ...

  2. CAS服务器集群和客户端集群环境下的单点登录和单点注销解决方案

    CAS的集群环境,包括CAS的客户应用是集群环境,以及CAS服务本身是集群环境这两种情况.在集群环境下使用CAS,要解决两个问题,一是单点退出(注销)时,CAS如何将退出请求正确转发到用户sessio ...

  3. 分布式集群环境下,如何实现session共享一(应用场景)

    在web应用中,由于http的请求响应式,无状态.要记录用户相关的状态信息,比如电商网站的购物车,比如用户是否登录等,都需要使用session.我们知道session是由servlet容器创建和管理, ...

  4. 分布式集群环境下,如何实现session共享四(部署项目测试)

    这是分布式集群环境下,如何实现session共享系列的第四篇.在上一篇:分布式集群环境下,如何实现session共享三(环境搭建)中,已经准备好了相关的环境:tomcat.nginx.redis.本篇 ...

  5. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  6. 集群环境下,Session管理的几种手段

    集群环境下,Session管理的几种手段 1.Session复制 缺点:集群服务器间需要大量的通信进行Session复制,占用服务器和网络的大量资源. 由于所有用户的Session信息在每台服务器上都 ...

  7. 集群环境下的Session管理

    1. 集群环境下的管理HTTPSSession所遇到的问题 一台服务器对应这个一个session对象,无法在另外一个服务器互通 解决方法: 1. Session 的 Replication(复制)将当 ...

  8. 在Hadoop1.2.1分布式集群环境下安装hive0.12

    在Hadoop1.2.1分布式集群环境下安装hive0.12 ● 前言: 1. 大家最好通读一遍过后,在理解的基础上再按照步骤搭建. 2. 之前写过两篇<<在VMware下安装Ubuntu ...

  9. 在tomcat集群环境下redis实现分布式锁

    上篇介绍了redis在集群环境下如何解决session共享的问题.今天来讲一下如何解决分布式锁的问题 什么是分布式锁? 分布式锁就是在多个服务器中,都来争夺某一资源.这时候我们肯定需要一把锁是不是 , ...

随机推荐

  1. UNIX网络编程——带外数据

    许多传输层有带外数据的概念,它有时也称为经加速数据.其想法是一个连接的某端发生了重要的事情,而且该端希望迅速通告其对端.这里"迅速"意味着这种通知应该在已排队等待发送的任何&quo ...

  2. 【一天一道LeetCode】#232. Implement Queue using Stacks

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Impleme ...

  3. JAVA代码规范笔记(下)

    声明 17.推荐一行一个声明,因为这样有利于写注释.换句话说,下面的声明方法中, int level; // indentation level int size; // size of table ...

  4. JSP自定义标签之简单标签入门

    在sun官方文档上有下面这样一段话. 官方文档声明 public interface SimpleTag extends JspTag Interface for defining Simple Ta ...

  5. OpenCV3.0 3.1版本的改进

     摘要        OpenCV现在更新到了3.1版本,相对OpenCV2有了很大改进,其中对于硬件加速,移动开发(IOS,android)的支持成为亮点.      新版的OpenCV采用了内 ...

  6. 《C语言点滴》书评

    说起C语言方面的书,你最先想到的是哪一本?不论图书本身是好是坏,反正我想到的是谭浩强的<C程序设计>--它已然是一部"圣经"了.那么,为什么赵岩老师还要写一本<C ...

  7. TCP的流量控制与拥塞控制小结

    概述 为了提高信道的利用率TCP协议不使用停止等待协议,而是使用连续ARQ协议,意思就是可以连续发出若干个分组然后等待确认,而不是发送一个分组就停止并等待该分组的确认.其中TCP的流量控制与拥塞控制是 ...

  8. ffmbc——为广播电视以及专业用途量身定制的FFmpeg

    无意中发现了个为广播电视以及专业用途量身定制的FFmpeg.也是开源的,记录之. ffmbc 全称是 FFMedia Broadcast,是个改版的FFmpeg,有如下功能: 创建可以导入Final ...

  9. 实例说明Java中的null

    翻译人员: 铁锚 翻译时间: 2013年11月11日 原文链接: What exactly is null in Java? 让我们先来看下面的语句: String x = null; 1. 这个语句 ...

  10. 016-类与对象-OC笔记

    学习目标 1.[理解]对象在内存中的存储 2.[理解]nil和NULL 3.[了解]#pragma mark分组导航标记 4.[理解]方法与函数 5.[掌握]多文件开发 6.[掌握]对象和方法 7.[ ...