第四十章:基于SpringBoot & Quartz完成定時(shí)任務(wù)分布式多節(jié)點(diǎn)負(fù)載持久化

在上一章【第三十九章:基于SpringBoot & Quartz完成定時(shí)任務(wù)分布式單節(jié)點(diǎn)持久化】中我們已經(jīng)完成了任務(wù)的持久化秉沼,當(dāng)我們創(chuàng)建一個(gè)任務(wù)時(shí)任務(wù)會(huì)被quartz定時(shí)任務(wù)框架自動(dòng)持久化到數(shù)據(jù)庫(kù)太惠,我們采用的是SpringBoot項(xiàng)目托管的dataSource來(lái)完成的數(shù)據(jù)源提供昌罩,當(dāng)然也可以使用quartz內(nèi)部配置數(shù)據(jù)源方式,我們的標(biāo)題既然是提到了定時(shí)任務(wù)的分布式多節(jié)點(diǎn)俘种,那么怎么才算是多節(jié)點(diǎn)呢?當(dāng)有節(jié)點(diǎn)故障或者手動(dòng)停止運(yùn)行后是否可以自動(dòng)漂移任務(wù)到可用的分布式節(jié)點(diǎn)呢绝淡?

免費(fèi)教程專題

恒宇少年在博客整理三套免費(fèi)學(xué)習(xí)教程專題宙刘,由于文章偏多特意添加了閱讀指南,新文章以及之前的文章都會(huì)在專題內(nèi)陸續(xù)填充够委,希望可以幫助大家解惑更多知識(shí)點(diǎn)荐类。

本章目標(biāo)

  1. 完成定時(shí)任務(wù)分布式多節(jié)點(diǎn)配置,當(dāng)單個(gè)節(jié)點(diǎn)關(guān)閉時(shí)其他節(jié)點(diǎn)自動(dòng)接管定時(shí)任務(wù)茁帽。
  2. 創(chuàng)建任務(wù)時(shí)傳遞自定義參數(shù)玉罐,方便任務(wù)處理后續(xù)業(yè)務(wù)邏輯。

SpringBoot 企業(yè)級(jí)核心技術(shù)學(xué)習(xí)專題


專題 專題名稱 專題描述
001 Spring Boot 核心技術(shù) 講解SpringBoot一些企業(yè)級(jí)層面的核心組件
002 Spring Boot 核心技術(shù)章節(jié)源碼 Spring Boot 核心技術(shù)簡(jiǎn)書每一篇文章碼云對(duì)應(yīng)源碼
003 Spring Cloud 核心技術(shù) 對(duì)Spring Cloud核心技術(shù)全面講解
004 Spring Cloud 核心技術(shù)章節(jié)源碼 Spring Cloud 核心技術(shù)簡(jiǎn)書每一篇文章對(duì)應(yīng)源碼
005 QueryDSL 核心技術(shù) 全面講解QueryDSL核心技術(shù)以及基于SpringBoot整合SpringDataJPA
006 SpringDataJPA 核心技術(shù) 全面講解SpringDataJPA核心技術(shù)
007 SpringBoot核心技術(shù)學(xué)習(xí)目錄 SpringBoot系統(tǒng)的學(xué)習(xí)目錄潘拨,敬請(qǐng)關(guān)注點(diǎn)贊5跏洹!!

構(gòu)建項(xiàng)目

注意:我們本章項(xiàng)目需要結(jié)合上一章共同完成铁追,有一點(diǎn)要注意的是任務(wù)在持久化到數(shù)據(jù)庫(kù)內(nèi)時(shí)會(huì)保存任務(wù)的全路徑季蚂,如:com.hengyu.chapter39.timers.GoodStockCheckTimerquartz在運(yùn)行任務(wù)時(shí)會(huì)根據(jù)任務(wù)全路徑去執(zhí)行琅束,如果不一致則會(huì)提示找不到指定類扭屁,我們本章在創(chuàng)建項(xiàng)目時(shí)package需要跟上一章完全一致。

我們這里就不去直接創(chuàng)建新項(xiàng)目了涩禀,直接復(fù)制上一章項(xiàng)目的源碼為新的項(xiàng)目命名為Chapter40

配置分布式

在上一章配置文件quartz.properties中我們其實(shí)已經(jīng)為分布式做好了相關(guān)配置料滥,下面我們就來(lái)看一下分布式相關(guān)的配置。
分布式相關(guān)配置:

1. org.quartz.scheduler.instanceId : 定時(shí)任務(wù)的實(shí)例編號(hào)艾船,如果手動(dòng)指定需要保證每個(gè)節(jié)點(diǎn)的唯一性葵腹,因?yàn)?code>quartz不允許出現(xiàn)兩個(gè)相同instanceId的節(jié)點(diǎn)高每,我們這里指定為Auto就可以了,我們把生成編號(hào)的任務(wù)交給quartz践宴。

2. org.quartz.jobStore.isClustered: 這個(gè)屬性才是真正的開啟了定時(shí)任務(wù)的分布式配置鲸匿,當(dāng)我們配置為true時(shí)quartz框架就會(huì)調(diào)用ClusterManager來(lái)初始化分布式節(jié)點(diǎn)。

3. org.quartz.jobStore.clusterCheckinInterval:配置了分布式節(jié)點(diǎn)的檢查時(shí)間間隔阻肩,單位:毫秒带欢。
下面是quartz.properties配置文件配置信息:

#調(diào)度器實(shí)例名稱
org.quartz.scheduler.instanceName = quartzScheduler

#調(diào)度器實(shí)例編號(hào)自動(dòng)生成
org.quartz.scheduler.instanceId = AUTO

#持久化方式配置
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

#持久化方式配置數(shù)據(jù)驅(qū)動(dòng),MySQL數(shù)據(jù)庫(kù)
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#quartz相關(guān)數(shù)據(jù)表前綴名
org.quartz.jobStore.tablePrefix = QRTZ_

#開啟分布式部署
org.quartz.jobStore.isClustered = true
#配置是否使用
org.quartz.jobStore.useProperties = false

#分布式節(jié)點(diǎn)有效性檢查時(shí)間間隔磺浙,單位:毫秒
org.quartz.jobStore.clusterCheckinInterval = 10000

#線程池實(shí)現(xiàn)類
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

#執(zhí)行最大并發(fā)線程數(shù)量
org.quartz.threadPool.threadCount = 10

#線程優(yōu)先級(jí)
org.quartz.threadPool.threadPriority = 5

#配置為守護(hù)線程洪囤,設(shè)置后任務(wù)將不會(huì)執(zhí)行
#org.quartz.threadPool.makeThreadsDaemons=true

#配置是否啟動(dòng)自動(dòng)加載數(shù)據(jù)庫(kù)內(nèi)的定時(shí)任務(wù),默認(rèn)true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

當(dāng)我們啟動(dòng)任務(wù)節(jié)點(diǎn)時(shí)撕氧,會(huì)根據(jù)org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread屬性配置進(jìn)行是否自動(dòng)加載任務(wù)瘤缩,默認(rèn)true自動(dòng)加載數(shù)據(jù)庫(kù)內(nèi)的任務(wù)到節(jié)點(diǎn)。

測(cè)試分布式

上一章項(xiàng)目節(jié)點(diǎn)名稱:quartz-cluster-node-first
本章項(xiàng)目節(jié)點(diǎn)名稱:quartz-cluster-node-second

由于我們quartz-cluster-node-first的商品庫(kù)存檢查定時(shí)任務(wù)是每隔30秒執(zhí)行一次伦泥,所以任務(wù)除非手動(dòng)清除否則是不會(huì)被清空的剥啤,在運(yùn)行項(xiàng)目測(cè)試之前需要將application.yml配置文件的端口號(hào)、項(xiàng)目名稱修改下不脯,保證quartz-cluster-node-secondquartz-cluster-node-first端口號(hào)不一致府怯,可以同時(shí)運(yùn)行,修改后為:

spring:
    application:
        name: quzrtz-cluster-node-second
server:
  port: 8082

然后修改相應(yīng)控制臺(tái)輸出防楷,為了能夠區(qū)分任務(wù)執(zhí)行者是具體的節(jié)點(diǎn)牺丙。

Chapter40Application啟動(dòng)類修改日志輸出:
logger.info("【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-second 已啟動(dòng)】】】】】】");

GoodAddTimer商品添加任務(wù)類修改日志輸出:
logger.info("分布式節(jié)點(diǎn)quartz-cluster-node-second,商品添加完成后執(zhí)行任務(wù)复局,任務(wù)時(shí)間:{}",new Date());

GoodStockCheckTimer商品庫(kù)存檢查任務(wù)類修改日志輸出:
logger.info("分布式節(jié)點(diǎn)quartz-cluster-node-second冲簿,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:{}",new Date());

下面我們啟動(dòng)本章項(xiàng)目亿昏,查看控制臺(tái)輸出內(nèi)容峦剔,如下所示:

2017-11-12 10:28:39.969  INFO 11048 --- [           main] c.hengyu.chapter39.Chapter40Application  : 【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-second 已啟動(dòng)】】】】】】
2017-11-12 10:28:41.930  INFO 11048 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds
2017-11-12 10:28:41.959  INFO 11048 --- [lerFactoryBean]] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_yuqiyu1510453719308 started.
2017-11-12 10:28:51.963  INFO 11048 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: detected 1 failed or restarted instances.
2017-11-12 10:28:51.963  INFO 11048 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: Scanning for instance "yuqiyu1510450938654"'s failed in-progress jobs.
2017-11-12 10:28:51.967  INFO 11048 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: ......Freed 1 acquired trigger(s).
2017-11-12 10:29:00.024  INFO 11048 --- [ryBean_Worker-1] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)角钩,執(zhí)行時(shí)間:Sun Nov 12 10:29:00 CST 2017

可以看到項(xiàng)目啟動(dòng)完成后自動(dòng)分配的instanceIdyuqiyu1510450938654吝沫,生成的規(guī)則是當(dāng)前用戶的名稱+時(shí)間戳。然后ClusterManager分布式管理者自動(dòng)介入進(jìn)行掃描是否存在匹配的觸發(fā)器任務(wù)递礼,如果存在則會(huì)自動(dòng)執(zhí)行任務(wù)邏輯惨险,而商品庫(kù)存檢查定時(shí)任務(wù)確實(shí)由quartz-cluster-node-second進(jìn)行輸出的。

測(cè)試任務(wù)自動(dòng)漂移

下面我們也需要把quartz-cluster-node-first的輸出進(jìn)行修改脊髓,如下所示:

Chapter39Application啟動(dòng)類修改日志輸出:
logger.info("【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-first 已啟動(dòng)】】】】】】");

GoodAddTimer商品添加任務(wù)類修改日志輸出:
logger.info("分布式節(jié)點(diǎn)quartz-cluster-node-first平道,商品添加完成后執(zhí)行任務(wù),任務(wù)時(shí)間:{}",new Date());

GoodStockCheckTimer商品庫(kù)存檢查任務(wù)類修改日志輸出:
logger.info("分布式節(jié)點(diǎn)quartz-cluster-node-first供炼,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)一屋,執(zhí)行時(shí)間:{}",new Date());

接下來(lái)我們啟動(dòng)quartz-cluster-node-first,并查看控制臺(tái)的輸出內(nèi)容:

2017-11-12 10:34:09.750  INFO 192 --- [           main] c.hengyu.chapter39.Chapter39Application  : 【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-first 已啟動(dòng)】】】】】】
2017-11-12 10:34:11.690  INFO 192 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds
2017-11-12 10:34:11.714  INFO 192 --- [lerFactoryBean]] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_yuqiyu1510454049066 started.

項(xiàng)目啟動(dòng)完成后袋哼,定時(shí)節(jié)點(diǎn)并沒(méi)有實(shí)例化ClusterManager來(lái)完成分布式節(jié)點(diǎn)的初始化冀墨,因?yàn)?code>quartz檢測(cè)到有其他的節(jié)點(diǎn)正在處理任務(wù),這樣也是保證了任務(wù)執(zhí)行的唯一性涛贯。

關(guān)閉quartz-cluster-node-second

我們關(guān)閉quartz-cluster-node-second運(yùn)行的項(xiàng)目诽嘉,預(yù)計(jì)的目的可以達(dá)到quartz-cluster-node-first會(huì)自動(dòng)接管數(shù)據(jù)庫(kù)內(nèi)的任務(wù),完成任務(wù)執(zhí)行的自動(dòng)漂移弟翘,我們來(lái)查看quartz-cluster-node-first的控制臺(tái)輸出內(nèi)容:

2017-11-12 10:34:09.750  INFO 192 --- [           main] c.hengyu.chapter39.Chapter39Application  : 【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-first 已啟動(dòng)】】】】】】
2017-11-12 10:34:11.690  INFO 192 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds
2017-11-12 10:34:11.714  INFO 192 --- [lerFactoryBean]] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_yuqiyu1510454049066 started.
2017-11-12 10:41:11.793  INFO 192 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: detected 1 failed or restarted instances.
2017-11-12 10:41:11.793  INFO 192 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: Scanning for instance "yuqiyu1510453719308"'s failed in-progress jobs.
2017-11-12 10:41:11.797  INFO 192 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: ......Freed 1 acquired trigger(s).
2017-11-12 10:41:11.834  INFO 192 --- [ryBean_Worker-1] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-first虫腋,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 10:41:11 CST 2017

控制臺(tái)已經(jīng)輸出了持久的定時(shí)任務(wù)稀余,輸出節(jié)點(diǎn)是quartz-cluster-node-first悦冀,跟我們預(yù)計(jì)的一樣,節(jié)點(diǎn)quartz-cluster-node-first完成了自動(dòng)接管quartz-cluster-node-second的工作睛琳,而這個(gè)過(guò)程肯定有一段時(shí)間間隔盒蟆,而這個(gè)間隔可以修改quartz.properties配置文件內(nèi)的屬性org.quartz.jobStore.clusterCheckinInterval進(jìn)行調(diào)節(jié)。

關(guān)閉quartz-cluster-node-first

我們同樣可以測(cè)試啟動(dòng)任務(wù)節(jié)點(diǎn)quartz-cluster-node-second后师骗,再關(guān)閉quartz-cluster-node-first任務(wù)節(jié)點(diǎn)历等,查看quartz-cluster-node-second控制臺(tái)的輸出內(nèi)容:

2017-11-12 10:53:31.010  INFO 3268 --- [           main] c.hengyu.chapter39.Chapter40Application  : 【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-second 已啟動(dòng)】】】】】】
2017-11-12 10:53:32.967  INFO 3268 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds
2017-11-12 10:53:32.992  INFO 3268 --- [lerFactoryBean]] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_yuqiyu1510455210493 started.
2017-11-12 10:53:52.999  INFO 3268 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: detected 1 failed or restarted instances.
2017-11-12 10:53:52.999  INFO 3268 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: Scanning for instance "yuqiyu1510454049066"'s failed in-progress jobs.
2017-11-12 10:53:53.003  INFO 3268 --- [_ClusterManager] o.s.s.quartz.LocalDataSourceJobStore     : ClusterManager: ......Freed 1 acquired trigger(s).
2017-11-12 10:54:00.020  INFO 3268 --- [ryBean_Worker-1] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)辟癌,執(zhí)行時(shí)間:Sun Nov 12 10:54:00 CST 2017

得到的結(jié)果是同樣可以完成任務(wù)的自動(dòng)漂移寒屯。

如果兩個(gè)節(jié)點(diǎn)同時(shí)啟動(dòng),哪個(gè)節(jié)點(diǎn)先把節(jié)點(diǎn)信息注冊(cè)到數(shù)據(jù)庫(kù)就獲得了優(yōu)先執(zhí)行權(quán)黍少。

傳遞參數(shù)到任務(wù)

我們平時(shí)在使用任務(wù)時(shí)寡夹,如果是針對(duì)性比較強(qiáng)的業(yè)務(wù)邏輯,肯定需要特定的參數(shù)來(lái)完成業(yè)務(wù)邏輯的實(shí)現(xiàn)仍侥。

下面我們來(lái)模擬商品秒殺的場(chǎng)景要出,當(dāng)我們添加商品后自動(dòng)添加一個(gè)商品提前五分鐘的秒殺提醒,為關(guān)注該商品的用戶發(fā)送提醒消息农渊。
我們?cè)诠?jié)點(diǎn)quartz-cluster-node-first中添加秒殺提醒任務(wù)患蹂,如下所示:

package com.hengyu.chapter39.timers;

import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * 商品秒殺提醒定時(shí)器
 * 為關(guān)注該秒殺商品的用戶進(jìn)行推送提醒
 * ========================
 *
 * @author 恒宇少年
 * Created with IntelliJ IDEA.
 * Date:2017/11/12
 * Time:9:23
 * 碼云:http://git.oschina.net/jnyqy
 * ========================
 */
public class GoodSecKillRemindTimer
extends QuartzJobBean
{
    /**
     * logback
     */
    private Logger logger = LoggerFactory.getLogger(GoodSecKillRemindTimer.class);

    /**
     * 任務(wù)指定邏輯
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //獲取任務(wù)詳情內(nèi)的數(shù)據(jù)集合
        JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        //獲取商品編號(hào)
        Long goodId = dataMap.getLong("goodId");
        
        logger.info("分布式節(jié)點(diǎn)quartz-cluster-node-first,開始處理秒殺商品:{}砸紊,關(guān)注用戶推送消息.",goodId);

        //.../
    }
}

在秒殺提醒任務(wù)邏輯中传于,我們通過(guò)獲取JobDetailJobDataMap集合來(lái)獲取在創(chuàng)建任務(wù)的時(shí)候傳遞的參數(shù)集合,我們這里約定了goodId為商品的編號(hào)醉顽,在創(chuàng)建任務(wù)的時(shí)候傳遞到JobDataMap內(nèi)沼溜,這樣quartz在執(zhí)行該任務(wù)的時(shí)候就會(huì)自動(dòng)將參數(shù)傳遞到任務(wù)邏輯中,我們也就可以通過(guò)JobDataMap獲取到對(duì)應(yīng)的參數(shù)值游添。

設(shè)置秒殺提醒任務(wù)

我們找到節(jié)點(diǎn)項(xiàng)目quartz-cluster-node-first中的GoodInfoService系草,編寫方法buildGoodSecKillRemindTimer設(shè)置秒殺提醒任務(wù)通熄,如下所示:

/**
     * 構(gòu)建商品秒殺提醒定時(shí)任務(wù)
     * 設(shè)置五分鐘后執(zhí)行
     * @throws Exception
     */
    public void buildGoodSecKillRemindTimer(Long goodId) throws Exception
    {
        //任務(wù)名稱
        String name = UUID.randomUUID().toString();
        //任務(wù)所屬分組
        String group = GoodSecKillRemindTimer.class.getName();
        //秒殺開始時(shí)間
        long startTime = System.currentTimeMillis() + 1000 * 5 * 60;
        JobDetail jobDetail = JobBuilder
                .newJob(GoodSecKillRemindTimer.class)
                .withIdentity(name,group)
                .build();

        //設(shè)置任務(wù)傳遞商品編號(hào)參數(shù)
        jobDetail.getJobDataMap().put("goodId",goodId);

        //創(chuàng)建任務(wù)觸發(fā)器
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).startAt(new Date(startTime)).build();
        //將觸發(fā)器與任務(wù)綁定到調(diào)度器內(nèi)
        scheduler.scheduleJob(jobDetail,trigger);
    }

我們模擬秒殺提醒時(shí)間是添加商品后的5分鐘,我們通過(guò)調(diào)用jobDetail實(shí)例的getJobDataMap方法就可以獲取該任務(wù)數(shù)據(jù)集合找都,直接調(diào)用put方法就可以進(jìn)行設(shè)置指定key的值唇辨,該集合繼承了StringKeyDirtyFlagMap并且實(shí)現(xiàn)了Serializable序列化,因?yàn)樾枰獙?shù)據(jù)序列化到數(shù)據(jù)庫(kù)的qrtz_job_details表內(nèi)能耻。
修改保存商品方法赏枚,添加調(diào)用秒殺提醒任務(wù):

    /**
     * 保存商品基本信息
     * @param good 商品實(shí)例
     * @return
     */
    public Long saveGood(GoodInfoEntity good) throws Exception
    {
        goodInfoRepository.save(good);
        //構(gòu)建創(chuàng)建商品定時(shí)任務(wù)
        buildCreateGoodTimer();
        //構(gòu)建商品庫(kù)存定時(shí)任務(wù)
        buildGoodStockTimer();
        //構(gòu)建商品描述提醒定時(shí)任務(wù)
        buildGoodSecKillRemindTimer(good.getId());
        return good.getId();
    }

添加測(cè)試商品

下面我們調(diào)用節(jié)點(diǎn)quartz-cluster-node-first的測(cè)試Chapter39ApplicationTests.addGood方法完成商品的添加,由于我們的quartz-cluster-node-second項(xiàng)目并沒(méi)有停止晓猛,所以我們?cè)?code>quartz-cluster-node-second項(xiàng)目的控制臺(tái)查看輸出內(nèi)容:

2017-11-12 11:45:00.008  INFO 11652 --- [ryBean_Worker-5] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second饿幅,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 11:45:00 CST 2017
2017-11-12 11:45:30.013  INFO 11652 --- [ryBean_Worker-6] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second戒职,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)栗恩,執(zhí)行時(shí)間:Sun Nov 12 11:45:30 CST 2017
2017-11-12 11:45:48.230  INFO 11652 --- [ryBean_Worker-7] c.hengyu.chapter39.timers.GoodAddTimer   : 分布式節(jié)點(diǎn)quartz-cluster-node-second,商品添加完成后執(zhí)行任務(wù)帕涌,任務(wù)時(shí)間:Sun Nov 12 11:45:48 CST 2017
2017-11-12 11:46:00.008  INFO 11652 --- [ryBean_Worker-8] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second摄凡,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 11:46:00 CST 2017
2017-11-12 11:46:30.016  INFO 11652 --- [ryBean_Worker-9] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second蚓曼,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)亲澡,執(zhí)行時(shí)間:Sun Nov 12 11:46:30 CST 2017
2017-11-12 11:47:00.011  INFO 11652 --- [yBean_Worker-10] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)纫版,執(zhí)行時(shí)間:Sun Nov 12 11:47:00 CST 2017
2017-11-12 11:47:30.028  INFO 11652 --- [ryBean_Worker-1] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second床绪,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 11:47:30 CST 2017
2017-11-12 11:48:00.014  INFO 11652 --- [ryBean_Worker-2] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second其弊,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)癞己,執(zhí)行時(shí)間:Sun Nov 12 11:48:00 CST 2017
2017-11-12 11:48:30.013  INFO 11652 --- [ryBean_Worker-3] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)梭伐,執(zhí)行時(shí)間:Sun Nov 12 11:48:30 CST 2017
2017-11-12 11:49:00.010  INFO 11652 --- [ryBean_Worker-4] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second痹雅,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 11:49:00 CST 2017
2017-11-12 11:49:30.028  INFO 11652 --- [ryBean_Worker-5] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second糊识,執(zhí)行庫(kù)存檢查定時(shí)任務(wù)绩社,執(zhí)行時(shí)間:Sun Nov 12 11:49:30 CST 2017
2017-11-12 11:49:48.290  INFO 11652 --- [ryBean_Worker-6] c.h.c.timers.GoodSecKillRemindTimer      : 分布式節(jié)點(diǎn)quartz-cluster-node-second,開始處理秒殺商品:15赂苗,關(guān)注用戶推送消息.
2017-11-12 11:50:00.008  INFO 11652 --- [ryBean_Worker-7] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second愉耙,執(zhí)行庫(kù)存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Sun Nov 12 11:50:00 CST 2017

秒殺任務(wù)在添加完成商品后的五分鐘開始執(zhí)行的拌滋,而我們也正常的輸出了傳遞過(guò)去的goodId商品編號(hào)的參數(shù)朴沿,而秒殺提醒任務(wù)執(zhí)行一次后也被自動(dòng)釋放了。

總結(jié)

本章主要是結(jié)合上一章完成了分布式任務(wù)的講解,完成了測(cè)試持久化的定時(shí)任務(wù)自動(dòng)漂移赌渣,以及如何向定時(shí)任務(wù)傳遞參數(shù)魏铅。當(dāng)然在實(shí)際的開發(fā)過(guò)程中,任務(wù)創(chuàng)建是需要進(jìn)行封裝的坚芜,目的也是為了減少一些冗余代碼以及方面后期統(tǒng)一維護(hù)定時(shí)任務(wù)沦零。

本章源碼已經(jīng)上傳到碼云:
SpringBoot配套源碼地址:https://gitee.com/hengboy/spring-boot-chapter
SpringCloud配套源碼地址:https://gitee.com/hengboy/spring-cloud-chapter

作者個(gè)人 博客
使用開源框架 ApiBoot 助你成為Api接口服務(wù)架構(gòu)師

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市货岭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疾渴,老刑警劉巖千贯,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異搞坝,居然都是意外死亡搔谴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門桩撮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)敦第,“玉大人,你說(shuō)我怎么就攤上這事店量∥吖” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵融师,是天一觀的道長(zhǎng)右钾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)旱爆,這世上最難降的妖魔是什么舀射? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮怀伦,結(jié)果婚禮上脆烟,老公的妹妹穿的比我還像新娘。我一直安慰自己房待,他們只是感情好邢羔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吴攒,像睡著了一般张抄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洼怔,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天署惯,我揣著相機(jī)與錄音,去河邊找鬼镣隶。 笑死极谊,一個(gè)胖子當(dāng)著我的面吹牛诡右,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轻猖,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼帆吻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了咙边?” 一聲冷哼從身側(cè)響起猜煮,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎败许,沒(méi)想到半個(gè)月后王带,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡市殷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年愕撰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醋寝。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搞挣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出音羞,到底是詐尸還是另有隱情囱桨,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布黄选,位于F島的核電站蝇摸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏办陷。R本人自食惡果不足惜貌夕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望民镜。 院中可真熱鬧啡专,春花似錦、人聲如沸制圈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鲸鹦。三九已至慧库,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馋嗜,已是汗流浹背齐板。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甘磨。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓橡羞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親济舆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子卿泽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 定時(shí)任務(wù)在企業(yè)項(xiàng)目比較常用到,幾乎所有的項(xiàng)目都會(huì)牽扯該功能模塊滋觉,定時(shí)任務(wù)一般會(huì)處理指定時(shí)間點(diǎn)執(zhí)行某一些業(yè)務(wù)邏輯签夭、間...
    恒宇少年閱讀 30,382評(píng)論 22 96
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)椎侠,斷路器覆致,智...
    卡卡羅2017閱讀 134,628評(píng)論 18 139
  • from http://www.infoq.com/cn/articles/etcd-interpretation...
    小樹苗苗閱讀 13,940評(píng)論 3 38
  • 《分布式任務(wù)調(diào)度平臺(tái)XXL-JOB》 一、簡(jiǎn)介 1.1 概述 XXL-JOB是一個(gè)輕量級(jí)分布式任務(wù)調(diào)度框架肺蔚,其核心...
    許雪里閱讀 16,771評(píng)論 3 29
  • 假如你走過(guò)了初戀,步入了成年 經(jīng)歷了年歲的更改 你開啟了生活的里里外外應(yīng)有的憧憬和期待 你說(shuō)你想去一個(gè)遙想的地方儡羔,...
    詹迅閱讀 268評(píng)論 1 2