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

前几天接到项目需要定时重建索引的任务,一开始试了试Java自带的Timer,不知道是不是自己对Timer的了解还不够的原因,感觉Timer的功能有点弱,无法达到我的需求:需要在某一个固定时间内按某一个周期来执行任务,并且这些时间可供客户配置。最后还是用Spring定时器来解决。

这里顺便说下多实例定时重建lucene索引的问题,如果某个项目在同一台服务器上面部署了多个实例,多个实例共用同一份索引文件,那么如果想要实现定时重建索引的功能,就务必要阻止在定时时间到的时候几个实例同时触发并重建索引,很明显的问题:一来同时有多个进程对同一份索引文件进行操作,会引起冲突;二来是根本就没必要,且耗资源。所以这里我的解决方法是每次定时时间到了之后,在执行任务之前随机获取一个时间,如1-100秒中间的任意一个,等过了这个随机时间之后再进行重建索引操作,这样可以避免多个实例同一时刻触发任务,然后第一个做定时任务的会在服务器磁盘上建立一个标识文件,表示当前有实例在执行任务,其他实例过了随机时间后发现有该标识文件存在就不做任务了,当然该文件必须在执行完任务或者任务过程中有异常而导致操作停止时要删除掉!

第一步:编写执行任务的类,继承QuartzJobBean,我的任务内容在此就不写了,如下:

public class RebuildLuceneIndex extends QuartzJobBean{Log log = LogFactory.getLog(RebuildLuceneIndex.class);private KbsEntryManager kbsEntryManager;int timeout;@Overrideprotected void executeInternal(JobExecutionContext jec)throws JobExecutionException {//获取配置信息,如果客户没配置的话则不启动定时器,应把它关掉:if(没配置定时器){try {jec.getScheduler().shutdown();} catch (SchedulerException e) {log.error(e.getMessage(),e);}}else{//执行你的任务
}    }
}

哦对,应为注入了一个类,需提供set方法,上面的代码增加:

public void setKbsEntryManager(KbsEntryManager manager) {this.kbsEntryManager = manager;}

第二步:编写定时器配置文件,比如我的schedule-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="schedulerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"><property name="jobClass"><value>com.syni.im800.kb.schedule.RebuildLuceneIndex</value></property><property name="jobDataAsMap"><map><entry key="kbsEntryManager" value-ref="kbsEntryManager"/>      </map></property></bean>  <bean id="rebuildIndexTrigger" class="com.syni.im800.kb.schedule.InitializingCronTrigger"><property name="jobDetail"><ref bean="schedulerJobDetail"/></property><property name="cronExpression"><value>0 0 2 * * ?</value></property></bean> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref local="cronTrigger"/><ref local="rebuildIndexTrigger"/></list></property></bean>   </beans>

上面的配置说明一下,因为cronExpression需提供可配置功能,不能写死在xml里面,所以自己写了一个InitializingCronTrigger,继承CronTriggerBean,在里面重新配置cronExpression,所以这里配置的0 0 2 * * ?其实只是为了不让容器在启动的时候报错而已。

第三步:编写第二步中的rebuildIndexTrigger:

public class InitializingCronTrigger extends CronTriggerBean implements Serializable{Log log  = LogFactory.getLog(InitializingCronTrigger.class);String cronExpression;public InitializingCronTrigger(){};public void setCronExpression(String cronExpression_) {String day = AppConfig.getProperty(AppConfig.REBUILDINDEX_DAY_OF_WEEK);String hour = AppConfig.getProperty(AppConfig.REBUILDINDEX_HOUR_OF_DAY);if(day!=null && hour!=null){cronExpression = "0 0 "+hour+" ? * "+day;log.debug("#######cronExpression:"+cronExpression);}else{//这里随便设置一个值,到时间的时候会把定时器关闭cronExpression = "0 0 1 ? * *";}try {super.setCronExpression(cronExpression);   } catch (Exception e) {log.error(e.getMessage(),e);}}
}

说明:因为chedule-context.xml中为InitializingCronTrigger注入了cronExpression,所以这里提供set方法,这样每次定时器触发的时候会调用这个方法,然后我们就可以在里面读取我们配置文件里实际配置的值,从而构建我们的cronExpression了,上面的day,hour是我的程序从配置文件中读取用户配置的信息而已。

最后是在web.xml中配置chedule-context.xm,这一步应该不用多少了吧,如:

<!-- Context Configuration locations for Spring XML files --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/schedule-context.xml</param-value></context-param>

另外,关于Spring定时器的详细使用,如配置表达式等,可参考其他文章,下面是简单的介绍表达式的配置:

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://my.oschina.net/u/2317688/blog/508893

Spring定时器的使用-多实例下定时重建索引相关推荐

  1. Solr定时重建索引和增量更新

    新增jar包 新增solr-dataimport-scheduler.jar到所有节点tomcat\webapps\下solr项目的WEB-INF\lib下 下载地址: 为Solr配置监听器 修改所有 ...

  2. spring定时器@Scheduled的原理和实现分析

    目录 一 简单介绍 二 为什么要加@EnableScheduling, @Scheduled才生效 三 什么时候什么地方解析@Scheduled 四,思考 一 简单介绍 我们可以通过如下方式使用定时器 ...

  3. linux定时器多次,Spring 定时器执行两次

    Spring错误笔记 Spring定时器执行两次因为导入了两次 关于配置文件如下 对应的类有个定时执行检查的动作,但是动作中的日志每次输出两遍,一开始以为是log4j的输出导致的两条,找了半天没办法还 ...

  4. Spring 定时器

    本文向您介绍Spring定时器的两种实现方式,包括Java Timer定时和Quartz定时器,两种Spring定时器的实现方式各有优点,可结合具体项目考虑是否采用. 有两种流行Spring定时器配置 ...

  5. spring定时器分析

    spring定时器如何使用? 步骤1. 定义job bean 1.TaskScheduler构造 2.初始化相关服务 <bean id="xxxxScheduler" cla ...

  6. spring定时器(@Scheduled)

    spring定时器需要额外添加下面配置 一.配置文件 xmlns 额外添加下面的内容: xmlns:task="http://www.springframework.org/schema/t ...

  7. Java怎么使用spring定时器_浅析spring定时器的使用

    原生的Java定时器 使用Java.util包下的定时器也很简单,具体代码如下: //设置定时器开始时间 Date time = sdf.parse("2020-10-01 16:40:00 ...

  8. [spring-framework]Spring定时器的配置和使用

    开发中我们常常会做一些定时任务,这些任务有开始时间,并会按一定的周期或规则执行.如此我们在Java程序开发中使用定时器来处理定时任务. <!-- MessageRequestTask类中包含了m ...

  9. Spring 定时器结合线程池

    需求:Spring 定时器结合线程池处理工单 a.定时扫库查出一定数量的需要处理的工单 b.开启线程处理查出的工单 1,创建处理工单的task @Component("AppWorkOrde ...

最新文章

  1. vs2005常用快捷键
  2. 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 文章汇总及学习指南...
  3. 【SSL】【Apache】 使用向导配置 https/ssl
  4. android wear2.9新功能,Android Wear 2.0确认2月9日正式登场
  5. vue页面引入多个组件的方法
  6. wifi传输信息需要连接服务器,基于近场通信的WiFi传输连接方案.pdf
  7. JavaScript:正则表达式 分组
  8. 【路径规划】基于matlab蚁群算法机器人栅格地图路径规划【含Matlab源码 119期】
  9. 系统试运行报告是谁写的_“项目总结报告”如何写?5个方向16个关键要素:总结很全面...
  10. 域名信息备案管理系统php,PHP:ICP备案查询PHP源代码
  11. ad中按钮开关的符号_电工必备基础知识及电路的符号字母大全
  12. 怎样找到优质的APP推广渠道
  13. 工业级路由器和家用路由器的区别_工业路由器与家用路由器有什么区别?
  14. Linux文件I/O实验报告
  15. Grammar-based construction 语法驱动的构造
  16. 基本磁盘与动态磁盘 RAID磁盘冗余阵列区分(简单了解各种卷组)
  17. Linux-shell脚本基础
  18. vue实现PS效果,鼠标拖拽指令、十字辅助线、鼠标选点、打印页面指定内容、生成随机id、颜色选择器、div上输入文字(类似QQ截图输入文字)、vue图片上传转base64...
  19. 什么是接口测试?十年阿里测试人教你怎样做接口测试
  20. 新媒体短视频运营哪些内容

热门文章

  1. Android如何更新app的版本(中级)
  2. 莎拉波顿,莎曼莎考克斯——英伦设计VS美国设计
  3. Windows Azure AppFabric概述
  4. RMAN快速入门指南
  5. JPA EnableJpaAuditing 审计功能
  6. 关于一次性能调优的反思
  7. mysql中迅速插入百万条测试数据的方法
  8. B-树的一点既不形象又不恰当的比喻
  9. Android 资源保护问题——探索
  10. C语言课程设计—图书管理系统