예약된 작업을 지속적으로 구현하는 springboot+quartz를 소개하는 글입니다. 자세한 내용은 다음과 같습니다.
글이 길지만, 인내심을 갖고 있는 분들은 언제나 최종 답을 얻으실 수 있습니다. Xiaosheng은 타이밍을 위해 석영을 사용합니다. 어떤 단점이라도 용서해주세요.
우선
springboot 프로젝트에서 예약된 작업을 수행하는 것은 비교적 간단합니다. 이를 구현하는 가장 간단한 방법은 **@Scheduled 주석을 사용한 다음 애플리케이션에서 @EnableScheduling**을 사용하는 것입니다. 예약된 작업을 활성화하는 시작 클래스입니다.
예
@SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } // cron为每秒执行一次 @Scheduled(cron = "* * * * * ?") public void print(){ System.out.println("执行定时任务"); } }
######결과
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
예약된 작업 실행
간단한 예약된 작업은 이러한 방식으로 수행될 수 있습니다. cron 표현식의 결과는 작업 실행 사이의 간격입니다.
그러나
실제 개발에서는 많은 작업이 있을 수 있으며, 추가, 시작, 중지, 계속 등 개별/모든 작업을 수동으로 조작해야 합니다. 그러면 "Qianniu Class B..." BGM과 함께 석영이 등장합니다.
quartz
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
quartz
는 작업(작업) 트리거 조건을 정의하는 데 사용됩니다. 트리거 시간, 트리거 간격, 종료 시간 등
작업 작업
실행할 특정 작업 내용
쿼츠를 사용하려면
쿼츠를 사용하려면 quartz.properties에 구성 파일이 필요합니다. jar 패키지. 기본 구성 파일 quartz.properties는 quartz 패키지에서 찾을 수 있습니다.
# Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler Instance, if a different # properties file is not explicitly specified. # # 名字 org.quartz.scheduler.instanceName: DefaultQuartzScheduler org.quartz.scheduler.rmi.export: false org.quartz.scheduler.rmi.proxy: false org.quartz.scheduler.wrapJobExecutionInUserTransaction: false # 实例化ThreadPool时,使用的线程类为SimpleThreadPool org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool # 线程总个数 org.quartz.threadPool.threadCount: 10 # 线程的优先级 org.quartz.threadPool.threadPriority: 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 # 持久化方式,默认持久化在内存中,后面我们使用db的方式 org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
quartz 작업을 db에 유지하려면 공식적으로 정의된 데이터베이스 테이블이 필요합니다. 테이블의 sql 파일은 jar 패키지에서 찾을 수 있습니다. quartz
Coordinates org.quartz.impl .jdbcjobstore를 보면 다양한 데이터베이스를 포함하여 많은 sql 파일이 있음을 알 수 있습니다. 우리는 나중에 sql 문을 수동으로 실행할 필요가 없습니다. 우리는 프로젝트를 시작합니다.
고유한 속성 파일 만들기
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool # threadCount和threadPriority将以setter的形式注入ThreadPool实例 # 并发个数 org.quartz.threadPool.threadCount=10 # 优先级 org.quartz.threadPool.threadPriority=5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true org.quartz.jobStore.misfireThreshold=5000 #持久化使用的类 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX #数据库中表的前缀 org.quartz.jobStore.tablePrefix=QRTZ_ #数据源命名 org.quartz.jobStore.dataSource=qzDS #qzDS 数据源,我们使用hikaricp,默认的是c3p0 org.quartz.dataSource.qzDS.provider=hikaricp org.quartz.dataSource.qzDS.driver=com.mysql.cj.jdbc.Driver org.quartz.dataSource.qzDS.URL=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 org.quartz.dataSource.qzDS.user=root org.quartz.dataSource.qzDS.password=123456 org.quartz.dataSource.qzDS.maxConnections=10
기본 연결 풀을 사용하지 않으므로 이를 살펴보고 소스 코드를 얻으세요! org.quartz.utils 패키지에는 이름에서 알 수 있듯이 연결 풀 공급자의 소스 코드 일부인 org.quartz.utils가 있습니다. 그러면 HikariCpPoolingConnectionProvider 클래스가 PoolingConnectionProvider를 구현합니다. 직접 확인해 보세요. org.quartz.impl 아래의 StdSchedulerFactory에서 c3p0을 검색하여
public interface PoolingConnectionProvider extends ConnectionProvider { /** The pooling provider. */ String POOLING_PROVIDER = "provider"; /** The c3p0 pooling provider. */ String POOLING_PROVIDER_C3P0 = "c3p0"; /** The Hikari pooling provider. */ String POOLING_PROVIDER_HIKARICP = "hikaricp"; }
나머지를 직접 읽어보세요. 시작 소스 코드를 연구하는 것은 생각만큼 어렵거나 지루하지 않습니다(저도 소스 코드를 읽는 것을 좋아하지 않습니다). , 하지만 이 소스 코드에는 성취감이 조금 있는 것 같습니다.
주제 채널로 돌아가서 application.yml
if(poolingProvider != null && poolingProvider.equals(PoolingConnectionProvider.POOLING_PROVIDER_HIKARICP)) { cpClass = "org.quartz.utils.HikariCpPoolingConnectionProvider"; } else { cpClass = "org.quartz.utils.C3p0PoolingConnectionProvider"; }
initialize-schema 구성: 항상 프로젝트를 시작할 때마다 항상 데이터베이스 테이블을 초기화하고 테이블의 주요 위치를 자동으로 생성하는 프로세스입니다. 테이블이 없으면 예외가 발생하지만 다음에 프로젝트를 시작할 때 테이블이 이미 존재하므로 예외가 발생하지 않습니다. . job-store-type: jdbc는 작업 지속성 유형입니다. 우리는 jdbc
를 사용합니다. 구성 없이는 작업에 스프링 개체를 주입해야 할 수도 있습니다.
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver password: 123456 url: jdbc:mysql://localhost:3306/quartz?characterEncoding=UTF8&useSSL=false&serverTimezone=GMT%2B8 username: root quartz: jdbc: initialize-schema: always job-store-type: jdbc
석영 구성 파일 만들기
/** * @author: taoym * @date: 2020/6/4 11:32 * @desc: 一定要自定义JobFactory重写SpringBeanJobFactory的createJobInstance方法,否则在job中是获取不到spring容器中的bean的 */ @Component public class JobFactory extends SpringBeanJobFactory { @Autowired private AutowireCapableBeanFactory beanFactory; /** * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } }
트리거 구성 요소 만들기
@Configuration public class QuartzConfig { @Autowired private JobFactory jobFactory; /** * 读取quartz.properties 文件 * 将值初始化 * * @return */ @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(jobFactory); schedulerFactoryBean.setQuartzProperties(quartzProperties()); return schedulerFactoryBean; } /** * 初始化监听器 * * @return */ @Bean public QuartzInitializerListener executorListener() { return new QuartzInitializerListener(); } @Bean(name = "scheduler") public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } }
이 구성 요소를 사용하여 트리거를 얻으세요.
작업 만들기
public class TriggerComponent { /** * @author: taoym * @date: 2020/6/1 10:35 * @desc: 构建cron触发器 */ public static Trigger cronTrigger(String cron) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .build(); return cronTrigger; } public static Trigger cronTrigger(String cron, JobDataMap jobDataMap) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .usingJobData(jobDataMap) .build(); return cronTrigger; } }
jobExecutionContext. 여기에서 작업 그룹, 작업 이름, 트리거 그룹, 트리거 이름, 작업 세부 정보 및 기타 정보를 얻을 수 있습니다. 해당 주석은 동일한 인스턴스(jobdetail)가 단일 스레드에서만 실행되도록 허용하는 것입니다. job은 인터페이스, jobdetail은 구현 클래스, a는 특정 작업을 수행하는 데 100초가 걸리며, 제공한 타이머는 50초마다 작업을 수행한다는 것을 알 수 있습니다. 실행을 통해 실행을 위해서는 또 다른 스레드를 시작해야 합니다. DisallowConcurrentExecution을 사용한다는 것은 a가 작업을 완료하지 않은 경우 a가 스레드를 열고 현재 작업을 수행하는 것이 허용되지 않음을 의미합니다. 제 설명이 이해하기 쉬웠는지 모르겠네요!
필요에 따라 나만의 작업 목록을 만듭니다. 저는 예약된 작업을 크롤러(소형 크롤러)로 사용합니다
@DisallowConcurrentExecution public class TestJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { } }
작업을 추가할 때 석영을 처리하지 않고 작업을 데이터베이스에 넣기만 하면 됩니다. 당황하지 마십시오. 그는 나중에 유용할 것입니다. 이 테이블을 추가, 삭제, 수정 및 확인해야 합니다. 시스템의 작업 목록을 쿼리하여 단일 또는 모든 작업을 선택하여 실행을 시작합니다
작업 실행
CREATE TABLE `quartz_job` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `job_name` varchar(50) DEFAULT '' COMMENT '任务名', `job_group` varchar(50) DEFAULT '' COMMENT '任务组名称', `job_desc` varchar(255) DEFAULT '' COMMENT 'job描述', `cron` varchar(50) DEFAULT '' COMMENT 'cron表达式', `status` tinyint(1) DEFAULT '0' COMMENT '状态', `url` varchar(255) DEFAULT '' COMMENT '请求地址', `param` varchar(255) DEFAULT '' COMMENT '参数', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
마지막으로 코드를 다시 붙여넣었습니다. 이 튜토리얼의 내용에 따라 정상적으로 실행될 수 있습니다.
추천 튜토리얼: "PHP"
위 내용은 springboot+quartz는 예약된 작업을 지속적으로 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!