-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path210125-SpringBoot-集成Quartz作业调度.html
70 lines (68 loc) · 36.6 KB
/
210125-SpringBoot-集成Quartz作业调度.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE html><html lang="zh-CN"><head><meta name="generator" content="Hexo 3.9.0"><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta content="yes" name="apple-mobile-web-app-capable"><meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"><meta content="telephone=no" name="format-detection"><meta name="description" content><title>SpringBoot-集成Quartz作业调度 | zhiheng's blog</title><link rel="stylesheet" type="text/css" href="/css/style.css?v=1.0.0"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/normalize.css/normalize.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss/build/pure-min.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss/build/grids-responsive-min.css"><link rel="stylesheet" href="//cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css"><script type="text/javascript" src="//cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script><link rel="icon" mask sizes="any" href="/img/favicon.ico"><link rel="Shortcut Icon" type="image/x-icon" href="/img/favicon.ico"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><link rel="apple-touch-icon-precomposed" href="/apple-touch-icon.png"><link rel="alternate" type="application/atom+xml" href="/atom.xml"><script type="text/javascript" src="//cdn.jsdelivr.net/npm/clipboard/dist/clipboard.min.js"></script><script type="text/javascript" src="//cdn.jsdelivr.net/gh/codeseven/toastr/build/toastr.min.js"></script><link rel="stylesheet" href="//cdn.jsdelivr.net/gh/codeseven/toastr/build/toastr.min.css"></head><body><div class="body_container"><div id="header"><div class="site-name"><h1 class="hidden">SpringBoot-集成Quartz作业调度</h1><a id="logo" href="/.">zhiheng's blog</a><p class="description">喜于分享,勤于积累;欢迎关注我的微信公众号:治恒说说</p></div><div id="nav-menu"><a class="current" href="/."><i class="fa fa-home"> 首页</i></a><a href="/archives/"><i class="fa fa-archive"> 归档</i></a><a href="/about/"><i class="fa fa-user"> 关于</i></a><a href="/demo/"><i class="fa fa-square"> 有趣的代码</i></a></div></div><div class="pure-g" id="layout"><div class="pure-u-1 pure-u-md-3-4"><div class="content_container"><div class="post"><h1 class="post-title">SpringBoot-集成Quartz作业调度</h1><div class="post-meta">2021年01月25日<span> | </span><span class="category"><a href="/categories/Spring-Boot/">Spring Boot</a></span><script src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async></script><span id="busuanzi_container_page_pv"> | <span id="busuanzi_value_page_pv"></span><span> 阅读</span></span></div><div class="post-content"><p>在说 quartz 之前,我们先回顾一下 spring 的定时任务,使用相当简单,默认集成在 spring boot 中,所以在 spring boot 项目中无需额外添加依赖,无需配置,只需要加个注解就可以了,当然也可以实现动态添加删除定时任务,详情前往上一篇博文<a href="https://dddreams.github.io/210122-SpringBoot-%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1.html">SpringBoot-定时任务</a>,那为什么要使用 quartz 呢,主要还是考虑分布式的应用,下面我们就来看一下 spring boot 是怎么集成 quartz 的。</p>
<h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>简单介绍下 quartz,Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于Java实现。作为一个优秀的开源调度框架,Quartz具有以下特点:</p>
<ul>
<li>(1)强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;</li>
<li>(2)灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;</li>
<li>(3)分布式和集群能力。</li>
</ul>
<blockquote>
<p>Tips<br>还记得 spring boot 的三板斧吗?加依赖,写配置,添注解</p>
</blockquote>
<h2 id="加依赖"><a href="#加依赖" class="headerlink" title="加依赖"></a>加依赖</h2><p>引入 spring-boot-starter-quartz 的依赖<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--quartz定时任务依赖--></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.boot<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-boot-starter-quartz<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure></p>
<h2 id="写配置"><a href="#写配置" class="headerlink" title="写配置"></a>写配置</h2><p>无需配置</p>
<h2 id="加注解"><a href="#加注解" class="headerlink" title="加注解"></a>加注解</h2><p>无需注解</p>
<h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>我们需要新建一个 QuartzService 的类,由于代码较长,在这里就不贴了,想看具体代码,请前往<a href="https://github.com/dddreams/learn-spring-boot/blob/master/spring-boot-quartz/src/main/java/com/shure/quartz/QuartzService.java" target="_blank" rel="noopener">QuartzService.java</a>。quartz 的 Job 实现方式很多,不一定要用这种方式,只是笔者认为这是一种比较简单的实现。</p>
<p>新加一个测试类 QuartzTest<br><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">@SpringBootTest</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QuartzTest</span> {</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Logger logger = LoggerFactory.getLogger(QuartzTest.class);</span><br><span class="line"> @Autowired</span><br><span class="line"> <span class="keyword">private</span> QuartzService quartzService;</span><br><span class="line"> @Test</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">quartzTest</span><span class="params">()</span> </span>{</span><br><span class="line"> logger.info(<span class="string">"添加定时任务"</span>);</span><br><span class="line"> <span class="keyword">String</span> jobName = <span class="string">"test-1"</span>;</span><br><span class="line"> Map<<span class="keyword">String</span>, Object> <span class="built_in">map</span> = <span class="keyword">new</span> HashMap<>();</span><br><span class="line"> <span class="built_in">map</span>.<span class="built_in">put</span>(<span class="string">"test"</span>, <span class="string">"测试任务执行"</span>);</span><br><span class="line"> <span class="built_in">map</span>.<span class="built_in">put</span>(<span class="string">"name"</span>, jobName);</span><br><span class="line"> quartzService.deleteJob(jobName, <span class="string">"test"</span>);</span><br><span class="line"> quartzService.addJob(TestQuartz.class, jobName, <span class="string">"test"</span>, <span class="string">"0 */2 * * * ?"</span>, <span class="built_in">map</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>新建 Job 类,需要继承 QuartzJobBean<br><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">TestQuartz</span> <span class="keyword">extends</span> <span class="title">QuartzJobBean</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> static <span class="keyword">final</span> <span class="type">Logger</span> logger = <span class="type">LoggerFactory</span>.getLogger(<span class="type">TestQuartz</span><span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">protected</span> void executeInternal(<span class="type">JobExecutionContext</span> jobExecutionContext) <span class="keyword">throws</span> <span class="type">JobExecutionException</span> {</span><br><span class="line"> <span class="type">SimpleDateFormat</span> formatter = <span class="keyword">new</span> <span class="type">SimpleDateFormat</span>(<span class="string">"yyyy-MM-dd HH:mm:ss"</span>);</span><br><span class="line"> logger.info(<span class="string">"任务开始执行:"</span> + formatter.format(<span class="type">System</span>.currentTimeMillis()));</span><br><span class="line"> <span class="type">JobDataMap</span> jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();</span><br><span class="line"> <span class="type">String</span> test = jobDataMap.get(<span class="string">"test"</span>).toString();</span><br><span class="line"> <span class="type">String</span> jobName = jobDataMap.get(<span class="string">"name"</span>).toString();</span><br><span class="line"> logger.info(test + <span class="string">":"</span> + jobName);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>启动,运行 Test 类,便可添加一个任务,创建 Job 时需要的参数可以通过 <code>JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();</code>来获取,这样就完成了一个定时任务功能。</p>
<h2 id="Quartz-集群使用"><a href="#Quartz-集群使用" class="headerlink" title="Quartz 集群使用"></a>Quartz 集群使用</h2><p>一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,它又管理着其他的节点。这就意味着你必须对每个节点分别启动或停止。Quartz 集群中,独立的 Quartz 节点并不与另一其的节点或是管理节点通信,而是通过相同的数据库表来感知到另一 Quartz 应用的。</p>
<p>因为 Quartz 集群依赖于数据库,所以必须首先创建 Quartz 数据库表,Quartz 发布包中包括了所有被支持的数据库平台的SQL脚本。这些SQL脚本存放于 <code><quartz_home>/docs/dbTables</code> 目录下,总共12张表,不同版本,表个数可能不同。下面是具体表的说明:</p>
<ul>
<li>qrtz_blob_triggers : 以Blob 类型存储的触发器。</li>
<li>qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。</li>
<li>qrtz_cron_triggers:存放cron类型的触发器。</li>
<li>qrtz_fired_triggers:存放已触发的触发器。</li>
<li>qrtz_job_details:存放一个jobDetail信息。</li>
<li>qrtz_job_listeners:job监听器。</li>
<li>qrtz_locks: 存储程序的悲观锁的信息(假如使用了悲观锁)。</li>
<li>qrtz_paused_trigger_graps:存放暂停掉的触发器。</li>
<li>qrtz_scheduler_state:调度器状态。</li>
<li>qrtz_simple_triggers:简单触发器的信息。</li>
<li>qrtz_trigger_listeners:触发器监听器。</li>
<li>qrtz_triggers:触发器的基本信息。</li>
</ul>
<p>接下来,新建 quartz.yml 的配置文件,来覆盖默认的配置。<br><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">org:</span></span><br><span class="line"> <span class="attr">quartz:</span></span><br><span class="line"> <span class="attr">jobStore:</span></span><br><span class="line"> <span class="attr">useProperties:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">tablePrefix:</span> <span class="string">qrtz_</span></span><br><span class="line"> <span class="comment"># 开启集群模式</span></span><br><span class="line"> <span class="attr">isClustered:</span> <span class="literal">true</span></span><br><span class="line"> <span class="comment"># 集群实例检测时间间隔 ms</span></span><br><span class="line"> <span class="attr">clusterCheckinInterval:</span> <span class="number">5000</span></span><br><span class="line"> <span class="comment"># misfire 任务的超时阈值 ms</span></span><br><span class="line"> <span class="attr">misfireThreshold:</span> <span class="number">60000</span></span><br><span class="line"> <span class="attr">txIsolationLevelReadCommitted:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">class:</span> <span class="string">org.quartz.impl.jdbcjobstore.JobStoreTX</span></span><br><span class="line"> <span class="attr">driverDelegateClass:</span> <span class="string">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">scheduler:</span></span><br><span class="line"> <span class="attr">instanceId:</span> <span class="string">AUTO</span></span><br><span class="line"> <span class="attr">rmi.export:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">rmi.proxy:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">wrapJobExecutionInUserTransaction:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 工作线程的线程池设置</span></span><br><span class="line"> <span class="attr">threadPool:</span></span><br><span class="line"> <span class="attr">class:</span> <span class="string">org.quartz.simpl.SimpleThreadPool</span></span><br><span class="line"> <span class="attr">threadCount:</span> <span class="number">25</span></span><br><span class="line"> <span class="attr">threadPriority:</span> <span class="number">5</span></span><br><span class="line"> <span class="attr">threadsInheritContextClassLoaderOfInitializingThread:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure></p>
<p>这样 Quartz 集群就可以实现了。</p>
<h2 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h2><h3 id="1、Quartz-触发时间配置的三种方式"><a href="#1、Quartz-触发时间配置的三种方式" class="headerlink" title="1、Quartz 触发时间配置的三种方式"></a>1、Quartz 触发时间配置的三种方式</h3><ul>
<li>cron 方式:采用cronExpression表达式配置时间。</li>
<li>simple 方式:和JavaTimer差不多,可以指定一个开始时间和结束时间外加一个循环时间。</li>
<li>calendars 方式:可以和cron配合使用,用cron表达式指定一个触发时间规律,用calendar指定一个范围。</li>
</ul>
<p><strong>注意:cron方式需要用到的4张数据表: qrtz_triggers,qrtz_cron_triggers,qrtz_fired_triggers,qrtz_job_details</strong></p>
<h3 id="2、使用-quartz-遇到的问题"><a href="#2、使用-quartz-遇到的问题" class="headerlink" title="2、使用 quartz 遇到的问题"></a>2、使用 quartz 遇到的问题</h3><h4 id="2-1、在定时任务执行中-service-Autowired-注解不进来"><a href="#2-1、在定时任务执行中-service-Autowired-注解不进来" class="headerlink" title="2.1、在定时任务执行中 service @Autowired 注解不进来"></a>2.1、在定时任务执行中 service @Autowired 注解不进来</h4><p>创建 JobFactory 的 Bean,并在 SchedulerConfig 中添加到 SchedulerFactoryBean<br><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// JobFactory</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">JobFactory</span> <span class="keyword">extends</span> <span class="title">SpringBeanJobFactory</span> <span class="title">implements</span> <span class="title">ApplicationContextAware</span> </span>{</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> transient <span class="type">AutowireCapableBeanFactory</span> beanFactory;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> public void setApplicationContext(<span class="keyword">final</span> <span class="type">ApplicationContext</span> context) {</span><br><span class="line"> beanFactory = context.getAutowireCapableBeanFactory();</span><br><span class="line"> }</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">protected</span> <span class="type">Object</span> createJobInstance(<span class="keyword">final</span> <span class="type">TriggerFiredBundle</span> bundle) <span class="keyword">throws</span> <span class="type">Exception</span> {</span><br><span class="line"> <span class="keyword">final</span> <span class="type">Object</span> job = <span class="keyword">super</span>.createJobInstance(bundle);</span><br><span class="line"> beanFactory.autowireBean(job);</span><br><span class="line"> <span class="keyword">return</span> job;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>SchedulerConfig.java<br><figure class="highlight aspectj"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SchedulerConfig</span> </span>{</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> DataSource dataSource;</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> JobFactory jobFactory;</span><br><span class="line"> <span class="meta">@Bean</span></span><br><span class="line"> <span class="keyword">public</span> <span class="function">Properties <span class="title">quartzProperties</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>{</span><br><span class="line"> PropertiesFactoryBean propertiesFactoryBean = <span class="keyword">new</span> PropertiesFactoryBean();</span><br><span class="line"> propertiesFactoryBean.setLocation(<span class="keyword">new</span> ClassPathResource(<span class="string">"/quartz.yml"</span>));</span><br><span class="line"> propertiesFactoryBean.afterPropertiesSet();</span><br><span class="line"> <span class="function"><span class="keyword">return</span> propertiesFactoryBean.<span class="title">getObject</span><span class="params">()</span></span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="meta">@Bean</span></span><br><span class="line"> <span class="keyword">public</span> <span class="function">SchedulerFactoryBean <span class="title">schedulerFactoryBean</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>{</span><br><span class="line"> SchedulerFactoryBean factory = <span class="keyword">new</span> SchedulerFactoryBean();</span><br><span class="line"> factory.setSchedulerName(<span class="string">"Cluster_Scheduler"</span>);</span><br><span class="line"> factory.setDataSource(dataSource);</span><br><span class="line"> factory.setApplicationContextSchedulerContextKey(<span class="string">"applicationContext"</span>);</span><br><span class="line"> factory.setQuartzProperties(quartzProperties());</span><br><span class="line"> factory.setJobFactory(jobFactory);</span><br><span class="line"> <span class="keyword">return</span> factory;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h4 id="2-2、quartz-任务激活失败"><a href="#2-2、quartz-任务激活失败" class="headerlink" title="2.2、quartz 任务激活失败"></a>2.2、quartz 任务激活失败</h4><p>在Quartz中,当一个持久化的触发器会因为:</p>
<ol>
<li>调度器被关闭;</li>
<li>线程池没有可用线程;</li>
<li>项目重启;</li>
<li>任务的串行执行;</li>
</ol>
<p>而错过激活时间,就会发生激活失败(misfire)。</p>
<p>可以设置 quartz中CornTrigger使用的策略<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//所有的misfile任务马上执行</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = <span class="number">-1</span>;</span><br><span class="line"><span class="comment">//在Trigger中默认选择MISFIRE_INSTRUCTION_FIRE_ONCE_NOW 策略</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> MISFIRE_INSTRUCTION_SMART_POLICY = <span class="number">0</span>;</span><br><span class="line"><span class="comment">// CornTrigger默认策略,合并部分misfire,正常执行下一个周期的任务。</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//所有的misFire都不管,执行下一个周期的任务。</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> MISFIRE_INSTRUCTION_DO_NOTHING = <span class="number">2</span>;</span><br></pre></td></tr></table></figure></p>
<p>1、 通过setMisfireInstruction方法设置misfire策略。<br><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean<span class="params">()</span>;</span><br><span class="line">triggerFactoryBean.<span class="keyword">set</span>Name<span class="params">("corn_" + clazzName)</span>;</span><br><span class="line">triggerFactoryBean.<span class="keyword">set</span>JobDetail<span class="params">(jobFactory.getObject()</span>);</span><br><span class="line">triggerFactoryBean.<span class="keyword">set</span>CronExpression<span class="params">(quartzCorn)</span>;</span><br><span class="line">triggerFactoryBean.<span class="keyword">set</span>Group<span class="params">(QUARTZ_TRIGGER_GROUP)</span>;</span><br><span class="line"><span class="string">//</span>设置misfire策略</span><br><span class="line">triggerFactoryBean.<span class="keyword">set</span>MisfireInstruction<span class="params">(CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY)</span>;</span><br><span class="line">triggerFactoryBean.afterPropertiesSet<span class="params">()</span>;</span><br></pre></td></tr></table></figure></p>
<p>2、 也可以通过CronScheduleBuilder设置misfire策略。<br><figure class="highlight protobuf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule(<span class="string">"0/5 * * * * ?"</span>);</span><br><span class="line"><span class="comment">//MISFIRE_INSTRUCTION_DO_NOTHING </span></span><br><span class="line">csb.withMisfireHandlingInstructionDoNothing();</span><br><span class="line"><span class="comment">//MISFIRE_INSTRUCTION_FIRE_ONCE_NOW</span></span><br><span class="line">csb.withMisfireHandlingInstructionFireAndProceed();<span class="comment">//(默认)</span></span><br><span class="line"><span class="comment">//MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY</span></span><br><span class="line">csb.withMisfireHandlingInstructionIgnoreMisfires();</span><br></pre></td></tr></table></figure></p>
<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>任务调度在实际项目中会经常用到,Quartz 也是我们的不二选择,但是在高可用的系统中也存在不少问题,具体问题小伙伴们可以在留言区留言,我们一起共同探讨。</p>
<h2 id="参考与相关链接"><a href="#参考与相关链接" class="headerlink" title="参考与相关链接"></a>参考与相关链接</h2><p>示例代码:<a href="https://github.com/dddreams/learn-spring-boot/tree/master/spring-boot-quartz" target="_blank" rel="noopener">https://github.com/dddreams/learn-spring-boot/tree/master/spring-boot-quartz</a></p>
<p>Quartz 官网:<a href="http://www.quartz-scheduler.org/" target="_blank" rel="noopener">http://www.quartz-scheduler.org/</a></p>
<p>Quartz集群原理及配置应用:<a href="https://www.cnblogs.com/xiang--liu/p/10120105.html" target="_blank" rel="noopener">https://www.cnblogs.com/xiang–liu/p/10120105.html</a></p>
<p><div style="text-align:center;margin:0;" markdown="1"><img src="../img/ddAnswer.jpg" alt="ddAnswer" style="margin:0 auto;"></div></p>
<p style="text-align: center;margin:0;">更多文章请关注微信公众号: zhiheng博客</p>
<p style="text-align: center;margin:20 0;">如果文章对你有用,转发分享、点赞赞赏才是真爱 [斜眼笑]</p>
</div><div class="tags"><a href="/tags/Spring-Boot/"><i class="fa fa-tag"></i>Spring Boot</a></div><div class="post-nav"><a class="pre" href="/210127-SpringBoot-集成Swagger2文档生成.html">SpringBoot-集成Swagger2文档生成</a><a class="next" href="/210122-SpringBoot-定时任务.html">SpringBoot-定时任务</a></div></div></div></div><div class="pure-u-1-4 hidden_mid_and_down"><div id="sidebar"><div class="widget"><div class="search-form"><input id="local-search-input" placeholder="Search" type="text" name="q" results="0"><div id="local-search-result"></div></div></div><div class="widget"><div class="widget-title"><i class="fa fa-wechat"> 微信公众号</i></div><div class="tagcloud"><img src="/img/zhihengss.jpg" style="width: 80%"></div></div><div class="widget"><div class="widget-title"><i class="fa fa-folder-o"> 分类</i></div><ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Github/">Github</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Mysql/">Mysql</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Python/">Python</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Spring-Boot/">Spring Boot</a><span class="category-list-count">6</span></li></ul></div><div class="widget"><div class="widget-title"><i class="fa fa-star-o"> 标签</i></div><div class="tagcloud"><a href="/tags/杂谈/" style="font-size: 15px;">杂谈</a> <a href="/tags/Kotlin/" style="font-size: 15px;">Kotlin</a> <a href="/tags/Google/" style="font-size: 15px;">Google</a> <a href="/tags/微信/" style="font-size: 15px;">微信</a> <a href="/tags/Photo/" style="font-size: 15px;">Photo</a> <a href="/tags/旅行/" style="font-size: 15px;">旅行</a> <a href="/tags/go/" style="font-size: 15px;">go</a> <a href="/tags/总结/" style="font-size: 15px;">总结</a> <a href="/tags/推荐/" style="font-size: 15px;">推荐</a> <a href="/tags/Spring-Boot/" style="font-size: 15px;">Spring Boot</a> <a href="/tags/Java/" style="font-size: 15px;">Java</a> <a href="/tags/运维/" style="font-size: 15px;">运维</a> <a href="/tags/Mysql/" style="font-size: 15px;">Mysql</a> <a href="/tags/Github/" style="font-size: 15px;">Github</a> <a href="/tags/教程/" style="font-size: 15px;">教程</a> <a href="/tags/软件/" style="font-size: 15px;">软件</a> <a href="/tags/Python/" style="font-size: 15px;">Python</a> <a href="/tags/Excel/" style="font-size: 15px;">Excel</a> <a href="/tags/工具/" style="font-size: 15px;">工具</a> <a href="/tags/JavaScript/" style="font-size: 15px;">JavaScript</a> <a href="/tags/Test/" style="font-size: 15px;">Test</a> <a href="/tags/Chrome/" style="font-size: 15px;">Chrome</a> <a href="/tags/Css/" style="font-size: 15px;">Css</a> <a href="/tags/Html/" style="font-size: 15px;">Html</a> <a href="/tags/设计模式/" style="font-size: 15px;">设计模式</a> <a href="/tags/Web/" style="font-size: 15px;">Web</a> <a href="/tags/React-Native/" style="font-size: 15px;">React-Native</a> <a href="/tags/ES6/" style="font-size: 15px;">ES6</a></div></div><div class="widget"><div class="widget-title"><i class="fa fa-file-o"> 最近文章</i></div><ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/211206-github精选-github加速访问神器.html">github精选-github加速访问神器</a></li><li class="post-list-item"><a class="post-list-link" href="/211204-github精选-一款高颜值的Redis客户端.html">github精选-一款高颜值的Redis客户端</a></li><li class="post-list-item"><a class="post-list-link" href="/211203-Python读取Excel中的图片(二).html">Python读取Excel中的图片(二)</a></li><li class="post-list-item"><a class="post-list-link" href="/211124-github精选-Linux命令大全.html">github精选-Linux命令大全</a></li><li class="post-list-item"><a class="post-list-link" href="/211120-github精选-PeaZip一款好用又免费的压缩软件.html">github精选-PeaZip一款好用又免费的压缩软件</a></li><li class="post-list-item"><a class="post-list-link" href="/211116-使用Python读取Excel中的图片并对应到记录.html">使用Python读取Excel中的图片并对应到记录</a></li><li class="post-list-item"><a class="post-list-link" href="/211111-SpringRestTemplate的使用.html">Spring RestTemplate的使用</a></li><li class="post-list-item"><a class="post-list-link" href="/211108-github精选-秒杀系统设计与实现.html">github精选-秒杀系统设计与实现</a></li><li class="post-list-item"><a class="post-list-link" href="/210208-Mysql登录失败多次锁定配置.html">Mysql登录失败多次锁定配置</a></li><li class="post-list-item"><a class="post-list-link" href="/210206-SpringBoot-使用JdbcTemplate操作数据库.html">SpringBoot-使用JdbcTemplate操作数据库</a></li></ul></div><div class="widget"><div class="widget-title"><i class="fa fa-external-link"> 友情链接</i></div><ul></ul><a href="https://geektutu.com/" title="极客兔兔" target="_blank">极客兔兔</a><ul></ul><a href="https://www.itmuch.com/" title="周立的博客" target="_blank">周立的博客</a><ul></ul><a href="https://liwenzhou.com/" title="李文周的博客" target="_blank">李文周的博客</a><ul></ul><a href="https://github.com/dddreams/dddreams.github.io/issues" title="添加友链请提交Issues" target="_blank">添加友链请提交Issues</a></div></div></div><div class="pure-u-1 pure-u-md-3-4"><div id="footer">Copyright © 2021 <a href="/." rel="nofollow">zhiheng's blog.</a> Powered by<a rel="nofollow" target="_blank" href="https://hexo.io"> Hexo.</a><a rel="nofollow" target="_blank" href="https://github.com/tufu9441/maupassant-hexo"> Theme</a> by<a rel="nofollow" target="_blank" href="https://github.com/pagecho"> Cho.</a></div></div></div><a class="show" id="rocket" href="#top"></a><script type="text/javascript" src="/js/totop.js?v=1.0.0" async></script><script type="text/javascript" src="//cdn.jsdelivr.net/gh/fancyapps/fancybox/dist/jquery.fancybox.min.js" async></script><script type="text/javascript" src="/js/fancybox.js?v=1.0.0" async></script><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox/dist/jquery.fancybox.min.css"><link rel="stylesheet" type="text/css" href="/css/search.css?v=1.0.0"><script type="text/javascript" src="/js/search.js?v=1.0.0"></script><script>var search_path = 'search.xml';
if (search_path.length == 0) {
search_path = 'search.xml';
}
var path = '/' + search_path;
searchFunc(path, 'local-search-input', 'local-search-result');
</script><script type="text/javascript" src="/js/copycode.js" successtext="复制成功!"></script><link rel="stylesheet" type="text/css" href="/css/copycode.css"><script type="text/javascript" src="/js/codeblock-resizer.js?v=1.0.0"></script><script type="text/javascript" src="/js/smartresize.js?v=1.0.0"></script></div></body></html>