使用quartz数据库锁实现定时任务的分布式部署
,1.根据项目引用的quartz依赖版本,确定下载的quartz-distribution安装包,我项目引用的信息如下图所示;
2.解压,在\quartz-2.2.3-distribution\quartz-2.2.3\docs\dbTables路径下,寻找项目中使用的数据库类型对应的脚本文件,我用的是oracle,脚本信息如下;
-- delete from qrtz_fired_triggers;
-- delete from qrtz_simple_triggers;
-- delete from qrtz_simprop_triggers;
-- delete from qrtz_cron_triggers;
-- delete from qrtz_blob_triggers;
-- delete from qrtz_triggers;
-- delete from qrtz_job_details;
-- delete from qrtz_calendars;
-- delete from qrtz_paused_trigger_grps;
-- delete from qrtz_locks;
-- delete from qrtz_scheduler_state;
--
-- drop table qrtz_calendars;
-- drop table qrtz_fired_triggers;
-- drop table qrtz_blob_triggers;
-- drop table qrtz_cron_triggers;
-- drop table qrtz_simple_triggers;
-- drop table qrtz_simprop_triggers;
-- drop table qrtz_triggers;
-- drop table qrtz_job_details;
-- drop table qrtz_paused_trigger_grps;
-- drop table qrtz_locks;
-- drop table qrtz_scheduler_state; CREATE TABLE qrtz_job_details
(
SCHED_NAME VARCHAR2(120) NOT NULL,
JOB_NAME VARCHAR2(200) NOT NULL,
JOB_GROUP VARCHAR2(200) NOT NULL,
DESCRIPTION VARCHAR2(250) NULL,
JOB_CLASS_NAME VARCHAR2(250) NOT NULL,
IS_DURABLE VARCHAR2(1) NOT NULL,
IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
JOB_DATA BLOB NULL,
CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE qrtz_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
JOB_NAME VARCHAR2(200) NOT NULL,
JOB_GROUP VARCHAR2(200) NOT NULL,
DESCRIPTION VARCHAR2(250) NULL,
NEXT_FIRE_TIME NUMBER(13) NULL,
PREV_FIRE_TIME NUMBER(13) NULL,
PRIORITY NUMBER(13) NULL,
TRIGGER_STATE VARCHAR2(16) NOT NULL,
TRIGGER_TYPE VARCHAR2(8) NOT NULL,
START_TIME NUMBER(13) NOT NULL,
END_TIME NUMBER(13) NULL,
CALENDAR_NAME VARCHAR2(200) NULL,
MISFIRE_INSTR NUMBER(2) NULL,
JOB_DATA BLOB NULL,
CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE qrtz_simple_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
REPEAT_COUNT NUMBER(7) NOT NULL,
REPEAT_INTERVAL NUMBER(12) NOT NULL,
TIMES_TRIGGERED NUMBER(10) NOT NULL,
CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_cron_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
CRON_EXPRESSION VARCHAR2(120) NOT NULL,
TIME_ZONE_ID VARCHAR2(80),
CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_simprop_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
STR_PROP_1 VARCHAR2(512) NULL,
STR_PROP_2 VARCHAR2(512) NULL,
STR_PROP_3 VARCHAR2(512) NULL,
INT_PROP_1 NUMBER(10) NULL,
INT_PROP_2 NUMBER(10) NULL,
LONG_PROP_1 NUMBER(13) NULL,
LONG_PROP_2 NUMBER(13) NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR2(1) NULL,
BOOL_PROP_2 VARCHAR2(1) NULL,
CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_blob_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
BLOB_DATA BLOB NULL,
CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_calendars
(
SCHED_NAME VARCHAR2(120) NOT NULL,
CALENDAR_NAME VARCHAR2(200) NOT NULL,
CALENDAR BLOB NOT NULL,
CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE qrtz_paused_trigger_grps
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_fired_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
ENTRY_ID VARCHAR2(95) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
INSTANCE_NAME VARCHAR2(200) NOT NULL,
FIRED_TIME NUMBER(13) NOT NULL,
SCHED_TIME NUMBER(13) NOT NULL,
PRIORITY NUMBER(13) NOT NULL,
STATE VARCHAR2(16) NOT NULL,
JOB_NAME VARCHAR2(200) NULL,
JOB_GROUP VARCHAR2(200) NULL,
IS_NONCONCURRENT VARCHAR2(1) NULL,
REQUESTS_RECOVERY VARCHAR2(1) NULL,
CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE qrtz_scheduler_state
(
SCHED_NAME VARCHAR2(120) NOT NULL,
INSTANCE_NAME VARCHAR2(200) NOT NULL,
LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
CHECKIN_INTERVAL NUMBER(13) NOT NULL,
CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE qrtz_locks
(
SCHED_NAME VARCHAR2(120) NOT NULL,
LOCK_NAME VARCHAR2(40) NOT NULL,
CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
); create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); commit;
注意,一定要在下面加上commit;原文件是没有的。
mysql脚本:
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
); CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
); CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
); CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
); CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
); CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
); CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
); CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
); CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
); CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
); CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
); commit;
3.建好表后,开始写java代码了,首先是2个配置文件,quartz.properties和spring-quartz.xml,其中spring-quartz.xml要随项目加载启动,可以放在spring启动文件里面或者通过listener启动。
我是通过在web.xml里
然后在applicationContext-bean.xml里面设置需要启动加载的xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd"> <!--===用于解耦框架,启动自定义框架===-->
<import resource="classpath*:resource/applicationContext-master.xml"/>
<import resource="classpath*:resource/applicationContext-slaveone-dao.xml"/>
<import resource="classpath*:resource/applicationContext-slavetwo-dao.xml"/>
<import resource="classpath*:resource/applicationContext-rmkj-dao.xml"/>
<import resource="classpath*:resource/applicationContext-quartz.xml"/>
<import resource="classpath*:resource/applicationContext-thread-pool.xml"/>
<import resource="classpath*:resource/applicationContext-redis.xml"/>
<import resource="classpath*:resource/applicationContext-service.xml"/>
<import resource="classpath*:resource/applicationContext-shiro.xml"/>
<import resource="classpath*:resource/applicationContext-transaction.xml"/>
<import resource="classpath*:resource/spring-quartz.xml"/>
</beans>
在上面的这些xml里面,最好是第一个加上把所有properties文件加载起来。
quartz.properties:
#============================================================================
# Configure JobStore
# Using Spring datasource in quartzJobsConfig.xml
# Spring uses LocalDataSourceJobStore extension of JobStoreCMT
#============================================================================
org.quartz.jobStore.useProperties=true
#quartz存储任务相关数据的表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
#是否启用集群,启用,改为true,注意:启用集群后,必须配置数据源,否则quartz调度器会初始化失败
org.quartz.jobStore.isClustered = true
#集群中服务器相互检测间隔,每台服务器都会按照下面配置的时间间隔往服务器中更新自己的状态,如果某台服务器超过以下时间没有checkin,调度器就会认为该台服务器已经down掉,不会再分配任务给该台服务器
org.quartz.jobStore.clusterCheckinInterval = 5000
#表示如果某个任务到达执行时间,而此时线程池中没有可用线程时,任务等待的最大时间,如果等待时间超过下面配置的值(毫秒),本次就不在执行,而等待下一次执行时间的到来,可根据任务量和负责程度来调整
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.txIsolationLevelReadCommitted = true
#实现集群时,任务的存储实现方式,org.quartz.impl.jdbcjobstore.JobStoreTX表示数据库存储
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate #============================================================================
# Configure Main Scheduler Properties
# Needed to manage cluster instances
#============================================================================
#集群中每台服务器自己的id,AUTO表示自动生成
org.quartz.scheduler.instanceId=AUTO
#配置集群时,quartz调度器的id,由于配置集群时,只有一个调度器,必须保证每个服务器该值都相同,可以不用修改,只要每个ams都一样就行
org.quartz.scheduler.instanceName=MY_CLUSTERED_JOB_SCHEDULER
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false #============================================================================
# Configure ThreadPool
#============================================================================
#quartz线程池的实现类
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#quartz线程池中线程数,可根据任务数量和负责度来调整
org.quartz.threadPool.threadCount = 10
#quartz线程优先级
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
spring-quartz.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.ra.quartz"/>
<!--如果项目没有配置数据源信息,需配置dataSource信息-->
<!--
<bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="/jndi/quartz"/>
</bean>
-->
<!-- 分布式事务配置 start -->
<!-- 配置线程池-->
<bean name="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="15"/>
<property name="maxPoolSize" value="25"/>
<property name="queueCapacity" value="100"/>
</bean> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 配置调度任务-->
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:resource/quartz.properties"/>
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/> <!-- 任务唯一的名称,将会持久化到数据库-->
<property name="schedulerName" value="baseScheduler"/> <!-- 每台集群机器部署应用的时候会更新触发器-->
<property name="overwriteExistingJobs" value="true"/>
<property name="applicationContextSchedulerContextKey" value="appli"/> <property name="jobFactory">
<bean class="com.ra.quartz.AutowiringSpringBeanJobFactory"/>
</property> <property name="triggers">
<list>
<!-- <ref bean="printCurrentTimeScheduler"/>
<ref bean="tenSecondsScheduler"/> -->
<ref bean="calculateTravelInfoScheduler"/>
<ref bean="dealPatchTrackScheduler"/>
<ref bean="deleteOtherMediaScheduler"/>
<ref bean="deleteWeatherScheduler"/>
<ref bean="evaluationDriverScheduler"/>
<ref bean="reportCreateMonthDataScheduler"/>
<ref bean="reportCreateWeekExcelAndImageScheduler"/>
<ref bean="reportCreateWeekWordScheduler"/>
<!--<ref bean="rMKJFaceIdentityScheduler"/>
<ref bean="selectWeatherInfoScheduler"/>
--><ref bean="statisticsCarOnlineHighRiskCountScheduler"/>
<ref bean="statisticsEveryTimeScheduler"/>
<ref bean="sycroRmkjCarInfoScheduler"/>
<ref bean="updateDriverSeqNoScheduler"/>
<ref bean="updatePBWUserInfoScheduler"/>
<ref bean="updateStatusScheduler"/>
<ref bean="updateTruckRiskOnTimeBy20secondsScheduler"/>
</list>
</property>
<property name="jobDetails">
<list>
<!-- <ref bean="printCurrentTimeJobs"/>
<ref bean="tenSecondsJobs"/> -->
<ref bean="calculateTravelInfoJobs"/>
<ref bean="dealPatchTrackJobs"/>
<ref bean="deleteOtherMediaJobs"/>
<ref bean="deleteWeatherJobs"/>
<ref bean="evaluationDriverJobs"/>
<ref bean="reportCreateMonthDataJobs"/>
<ref bean="reportCreateWeekExcelAndImageJobs"/>
<ref bean="reportCreateWeekWordJobs"/>
<!--<ref bean="rMKJFaceIdentityJobs"/>
<ref bean="selectWeatherInfoJobs"/>
--><ref bean="statisticsCarOnlineHighRiskCountJobs"/>
<ref bean="statisticsEveryTimeJobs"/>
<ref bean="sycroRmkjCarInfoJobs"/>
<ref bean="updateDriverSeqNoJobs"/>
<ref bean="updatePBWUserInfoJobs"/>
<ref bean="updateStatusJobs"/>
<ref bean="updateTruckRiskOnTimeBy20secondsJobs"/>
</list>
</property> <property name="taskExecutor" ref="executor"/> </bean> <!-- 配置Job详情 -->
<!-- <bean name="printCurrentTimeJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.PrintCurrentTimeJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="tenSecondsJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.TenSecondsJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> --> <bean name="calculateTravelInfoJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.CalculateTravelInfoJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="dealPatchTrackJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.DealPatchTrackJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="deleteOtherMediaJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.DeleteOtherMediaJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="deleteWeatherJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.DeleteWeatherJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="evaluationDriverJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.EvaluationDriverJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="reportCreateMonthDataJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.ReportCreateMonthDataJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="reportCreateWeekExcelAndImageJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.ReportCreateWeekExcelAndImageJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="reportCreateWeekWordJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.ReportCreateWeekWordJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <!-- <bean name="rMKJFaceIdentityJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.RMKJFaceIdentityJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="selectWeatherInfoJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.SelectWeatherInfoJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> --> <bean name="statisticsCarOnlineHighRiskCountJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.StatisticsCarOnlineHighRiskCountJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="statisticsEveryTimeJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.StatisticsEveryTimeJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="sycroRmkjCarInfoJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.SycroRmkjCarInfoJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="updateDriverSeqNoJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.UpdateDriverSeqNoJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="updatePBWUserInfoJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.UpdatePBWUserInfoJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="updateStatusJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.UpdateStatusJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <bean name="updateTruckRiskOnTimeBy20secondsJobs" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.ra.quartz.jobs.UpdateTruckRiskOnTimeBy20secondsJobs"/>
<property name="durability" value="true"/>
<property name="requestsRecovery" value="false"/>
</bean> <!-- 配置触发时间 -->
<!-- <bean name="printCurrentTimeScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="printCurrentTimeJobs"/>
<property name="cronExpression">
<value>0/5 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="tenSecondsScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="tenSecondsJobs"/>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean> -->
<bean name="calculateTravelInfoScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="calculateTravelInfoJobs"/>
<property name="cronExpression">
<value>0 0 6 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="dealPatchTrackScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="dealPatchTrackJobs"/>
<property name="cronExpression">
<value>0/20 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="deleteOtherMediaScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="deleteOtherMediaJobs"/>
<property name="cronExpression">
<value>0 0 2 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="deleteWeatherScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="deleteWeatherJobs"/>
<property name="cronExpression">
<value>0 03 0/1 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="evaluationDriverScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="evaluationDriverJobs"/>
<property name="cronExpression">
<value>0 0 22 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="reportCreateMonthDataScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="reportCreateMonthDataJobs"/>
<property name="cronExpression">
<value>0 15 1 1 * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="reportCreateWeekExcelAndImageScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="reportCreateWeekExcelAndImageJobs"/>
<property name="cronExpression">
<value>0 0 2 ? * MON</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="reportCreateWeekWordScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="reportCreateWeekWordJobs"/>
<property name="cronExpression">
<value>0 0 4 ? * MON</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<!-- <bean name="rMKJFaceIdentityScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="rMKJFaceIdentityJobs"/>
<property name="cronExpression">
<value>0/5 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean> -->
<!-- <bean name="selectWeatherInfoScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="selectWeatherInfoJobs"/>
<property name="cronExpression">
<value>0/5 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean> -->
<bean name="statisticsCarOnlineHighRiskCountScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="statisticsCarOnlineHighRiskCountJobs"/>
<property name="cronExpression">
<value>0/60 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="statisticsEveryTimeScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="statisticsEveryTimeJobs"/>
<property name="cronExpression">
<value>0 03 0/1 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="sycroRmkjCarInfoScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="sycroRmkjCarInfoJobs"/>
<property name="cronExpression">
<value>0 0/2 * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="updateDriverSeqNoScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="updateDriverSeqNoJobs"/>
<property name="cronExpression">
<value>0 0 0 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="updatePBWUserInfoScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="updatePBWUserInfoJobs"/>
<property name="cronExpression">
<value>0 55 18 14 * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="updateStatusScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="updateStatusJobs"/>
<property name="cronExpression">
<value>0 0 1 * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<bean name="updateTruckRiskOnTimeBy20secondsScheduler" class="com.ra.quartz.PersistableCronTriggerFactoryBean">
<property name="jobDetail" ref="updateTruckRiskOnTimeBy20secondsJobs"/>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
<property name="timeZone">
<value>GMT+8:00</value>
</property>
</bean>
<!-- 分布式事务配置 end -->
</beans>
4.编码AutowiringSpringBeanJobFactory类,作用是:使用@autowire来自动装配类
package com.ra.quartz; import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory; /**
* @Auther: lanhao
* @Date: 2018/8/14 11:37
* @Description:
*/
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory; public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
beanFactory = applicationContext.getAutowireCapableBeanFactory();
} @Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
5.编写PersistableCronTriggerFactoryBean类
package com.ra.quartz; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import java.text.ParseException; /**
* @Auther: lanhao
* @Date: 2018/8/14 14:06
* @Description:
*/
public class PersistableCronTriggerFactoryBean extends CronTriggerFactoryBean{
@Override
public void afterPropertiesSet() throws ParseException
{
super.afterPropertiesSet();
getJobDataMap().remove(getObject().getJobKey().getName());
}
}
6.下面就是具体的job类了,以其中一个例子为类;
UpdateStatusJobs:
package com.ra.quartz.jobs; import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean; import com.ra.quartz.UpdateStatusQuartz; public class UpdateStatusJobs extends QuartzJobBean{ @Autowired
private UpdateStatusQuartz clusterQuartz; @Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
clusterQuartz.updateStatus();
} }
注:@Autowired注解能用就是因为上面的AutowiringSpringBeanJobFactory类。
UpdateStatusQuartz类就是具体的业务逻辑代码了,里面写的方法全部在job里面调用就行了。
一个定时任务一个job类。
使用quartz数据库锁实现定时任务的分布式部署的更多相关文章
- quartz详解3:quartz数据库集群-锁机制
http://blog.itpub.NET/11627468/viewspace-1764753/ 一.quartz数据库锁 其中,QRTZ_LOCKS就是Quartz集群实现同步机制的行锁表,其表结 ...
- 【redis】分布式锁实现,与分布式定时任务
如果你还不知道redis的基本命令与基本使用方法,请看 [redis]redis基础命令学习集合 写在前面 redis辣么多数据结构,这么多命令,具体一点,都可以应用在什么场景呢?用来解决什么具体的问 ...
- springboot和quartz整合实现动态定时任务(持久化单节点)
Quartz是一个完全由java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,它支持定时任务持久化到数据库,从而避免了重启服务器时任务丢失,支持分布式多节点,大大的 ...
- 整理分布式锁:业务场景&分布式锁家族&实现原理
1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...
- ASP.NET Core2.2+Quartz.Net 实现web定时任务
作为一枚后端程序狗,项目实践常遇到定时任务的工作,最容易想到的的思路就是利用Windows计划任务/wndows service程序/Crontab程序等主机方法在主机上部署定时任务程序/脚本. 但是 ...
- web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)
这篇文章讲了 1.同步异步概念(消去很多疑惑),同步就是一件事一件事的做:sychronized就是保证线程一个一个的执行. 2.我们需要明白,锁机制有两个层面,一种是代码层次上的,如Java中的同步 ...
- Spring+Quartz实现动态添加定时任务
发布时间:2018-12-03 技术:spring4.0.2+quartz2.2.1 概述 在最近工作中,由于涉及到定时任务特别多,而这些工作又是由下属去完成的,在生成环境中经常会出现业务逻辑 ...
- 使用Quartz.net来执行定时任务
Quartz.net使用方法:http://www.cnblogs.com/lizichao1991/p/5707604.html 最近,项目中需要执行一个计划任务,组长就让我了解一下Quartz.n ...
- 看MySQL的参数调优及数据库锁实践有这一篇足够了
史上最强MySQL参数调优及数据库锁实践 1. 应用优化 1.2 减少对MySQL的访问 1.2.1 避免对数据进行重复检索 1.2.2 增加cache层 1.3 负载均衡 1.3.1 利用MySQL ...
随机推荐
- list add对象踩的坑
list 添加对象时,没有把new object写到循环体里,导致最后添加了相同的一个对象: public List<goods> find(String goodsname) { Lis ...
- Rk3288 双屏异显单触摸
系统版本:RK3288 android 5.1 设备同时有两个lcd,主屏是mipi接口,带有触摸屏,触摸屏是usb接口,副屏是hdmi接口,没有触摸屏,正常情况下,两个lcd显示相同内容,触摸屏一切 ...
- Axure RP 9 Beta 开放下载(更新激活密钥和汉化包)
2018年9月9号,7月9号来厦门入职,已经两个月了.这两个月的生活状态真心不好,一方面工作很忙(刚工作是这样?),虽然工资还可以,但总感觉性价比很低,自已对这份工作不够热爱也许.另一方面,来到新城市 ...
- JAVA用QRCode生成二维码
QRCode jar下载地址: 生成:http://www.swetake.com/qrcode/index-e.html 读取:https://zh.osdn.net/projects/qrcode ...
- Go VSCode配置编译task
菜单栏Tasks->Configure Tasks { "version": "2.0.0", "tasks": [ { " ...
- 关于linux - Centos 7 下DHCP服务的安装与配置
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP ...
- springboot2.X访问静态文件配置
config配置: @Configuration public class WebMvcConfig implements WebMvcConfigurer { /** * 跨域配置 * @retur ...
- 浏览器调起Hbuilder的APP
最近用Hbuilder来开发APP,测试各种功能,其中,最近测试到,要用这个浏览器调起APP的功能,我看官网有教程,但是有些可能刚工作没多久,所以,有些地方看不大明白,官方也没细说,所以 ...
- J Press the Button
BaoBao and DreamGrid are playing a game using a strange button. This button is attached to an LED li ...
- J - Printer Queue 优先队列与队列
来源poj3125 The only printer in the computer science students' union is experiencing an extremely heav ...