txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)

 241

前言

Hi,大家好,我是希留。

在项目的开发工程中,经常有需要定时任务调度的功能场景,比如,定时发送短信、定时抽取数据等。那遇到这种功能的时候应该怎么去做呢?本篇文章向大家介绍几种创建定时任务的方式。如果对你有帮助的话,还不忘点赞支持一下,感谢!文末附有源码

目录

一、单机环境下创建二、分布式环境下创建三、代码实现一、单机环境下创建

1、使用TimerTask创建定时任务Timer是jdk中提供的一个定时器类,通过该类可以为指定的定时任务进行配置。TimerTask类是一个定时任务类,该类实现了Runnable接口,缺点是Timer的内部只有一个线程,如果有多个任务的话就会顺序执行,这样我们的延迟时间和循环时间就会出现问题。

public class JobTimerTask { static long count = 0; public static void main(String[] args) { TimerTask timerTask = new TimerTask() { @Override public void run() { count++; System.out.println(count); } }; //创建timer对象设置间隔时间 Timer timer = new Timer(); // 间隔天数 long delay = 0; // 间隔毫秒数 long period = 1000; timer.scheduleAtFixedRate(timerTask, delay, period); }}2、使用线程池创建定时任务ScheduledExecutorService线程池:相对延迟或者周期作为定时任务调度,缺点是没有绝对的日期或者时间。

public class JobScheduledExecutorTask { public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hello ScheduledExecutorService定时任务!!"); } }; ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间 service.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS); }}3、使用spring内置定时任务@Scheduled 注解@Schedule注解:配置简单功能较多,如果系统使用单机的话可以优先考虑spring定时器。

@Component@Configuration //1.主要用于标记配置类,兼备Component的效果。@EnableScheduling // 2.开启定时任务public class ScheduleTask { @Scheduled(cron = "0/5 * * * * ?") //3.添加定时任务 //@Scheduled(fixedRate=5000) //或直接指定时间间隔,例如:5秒 private void configureTasks() { System.out.println("执行静态定时任务时间: " + LocalDateTime.now()); }}​二、分布式环境下创建

1、使用Quartz框架Quartz是一个开源的任务调度框架。基于定时、定期的策略来执行任务是它的核心功能。

Quartz 的常见集群方案是通过在数据库中配置定时器信息, 以数据库悲观锁的方式达到同一个任务始终只有一个节点在运行。亮点是保证节点高可用 (HA), 如果某一个节点挂了, 其他节点可以顶上。

缺点是同一个任务只能有一个节点运行,其他节点将不执行任务,性能低,资源浪费当碰到大量短任务时,各个节点频繁的竞争数据库锁,节点越多这种情况越严重。性能会很低下。

Quartz 的分布式仅解决了集群高可用的问题,并没有解决任务分片的问题,不能实现水平扩展。

下面带大家介绍一下两种整合Quartz框架实现定时任务调度的方式,一种是Spring整合的方式,比较繁琐,但是能更好的掌握原理。一种是SpringBoot整合的方式,使用SpirngBoot自带Quartz插件,可以快速集成。

1.1 Spring集成方式1.1.1 添加pom依赖!-- spring集成quartz定时任务--dependency groupIdorg.quartz-scheduler/groupId artifactIdquartz/artifactId/dependency!-- spring为了整合quartz及其他框架的中间环境包--dependency groupIdorg.springframework/groupId artifactIdspring-context-support/artifactId version5.2.3.RELEASE/version/dependency1.1.2 初始化Quartz的表如果需要做持久化的话,数据肯定是要存在数据库的,Quartz提供了相关的表结构,可以直接到官网下。本次demo中也有!

1.1.3 初始化自定义的定时任务表在自定义一张定时任务表,把所有的定时任务都集中起来,方便进行业务操作管理。

-- 定时任务表结构DROP TABLE IF EXISTS `schedule_job`;CREATE TABLE `schedule_job` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `bean` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'bean名称', `method` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '方法名', `params` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '参数', `cron` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'cron表达式', `status` tinyint(2) NOT NULL DEFAULT 1 COMMENT '状态。0:运行中;1:已暂停;2:已完成;3:运行失败;', `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务表' ROW_FORMAT = Dynamic;1.1.4 编写配置类@Configurationpublic class SchedulerConfig { @Autowired private TaskSchedulerFactory springJobFactory; public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { // 创建Scheduler的工厂 SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); factory.setJobFactory(springJobFactory); // quartz参数 factory.setQuartzProperties(this.convertProp()); factory.setSchedulerName("JavaSjzlScheduler"); // 延时启动 应用启动30秒后 factory.setStartupDelay(30); factory.setApplicationContextSchedulerContextKey("applicationContextKey"); // 可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 factory.setOverwriteExistingJobs(true); // 设置自动启动,默认为true factory.setAutoStartup(true); return factory; } private Properties convertProp() { // quartz参数,也可以写在配置文件里 Properties prop = new Properties(); // 实例名字 #默认或是自己改名字都行 prop.put("org.quartz.scheduler.instanceName", "JavaSjzlScheduler"); // #如果使用集群,instanceId必须唯一,设置成AUTO prop.put("org.quartz.scheduler.instanceId", "AUTO"); // 线程池配置 prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); // 并发个数 prop.put("org.quartz.threadPool.threadCount", "10"); // # 设置工作者线程的优先级(最大值10,最小值1,常用值5) prop.put("org.quartz.threadPool.threadPriority", "5"); // JobStore配置 #存储方式使用JobStoreTX,也就是数据库 prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX"); // 集群配置 prop.put("org.quartz.jobStore.isClustered", "true"); prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); prop.put("org.quartz.jobStore.misfireThreshold", "12000"); // #数据库中quartz表的表名前缀 prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); return prop; }}1.1.5 编写自定义的工厂类由于定时任务Job对象的实例化过程是在Quartz中进行的,需要把将Job Bean也纳入到Spring容器的管理之中,以便在Spring容器启动后,Scheduler自动开始工作,而在Spring容器关闭前,自动关闭Scheduler。

/** * @author Java升级之路 * @description 自定义的工厂类 创建job实例并将其纳入到Spring容器的管理之中 * @date 2021/7/1 */@Componentpublic class TaskSchedulerFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; protected Object creatJobInstance(TriggerFiredBundle bundle) throws Exception { //首先,调用父类的方法创建好quartz所需要的实例 Object jobInstance = super.createJobInstance(bundle); //然后,使用BeanFactory为创建好的Job实例进行属性自动装配,并将其纳入到Spring容器的管理之中 capableBeanFactory.autowireBean(jobInstance); return jobInstance; }}1.1.6 编写一个测试任务调度类** * @author Java升级之路 * @description 测试任务调度类 * @date 2021/7/1 */@Slf4j@Componentpublic class HelloJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 获得传入的参数 Object params = jobExecutionContext.getMergedJobDataMap().get(JobConstant.JOB_MAP_KEY); log.info("helloJob is running params={}, time:{}", params, new Date()); }}1.1.7 编写一个任务调度工具类把创建定时任务封装成一个工具类,方便业务上调用

/** * @author Java升级之路 * @description 执行任务工具类 * @date 2021/7/1 */public class ScheduleUtil { private final static String JOB_KEY = "JOB_" /** * 获取schedulerBean **/ private final static Scheduler scheduler = SpringContextUtil.getBean(Scheduler.class); /** * 创建定时任务 **/ public static void create(Long jobId, Job job) { try { //构建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleUtil.getJobClass(job.getBean()).getClass()) .withIdentity(getJobKey(jobId)) .build(); //表达式调度构建器(即任务执行的时间) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron()); //按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId)) .withSchedule(scheduleBuilder).build(); // 传入参数 jobDetail.getJobDataMap().put(JobConstant.JOB_MAP_KEY, job.getParams()); scheduler.scheduleJob(jobDetail, trigger); // 默认创建时任务设置为暂停 ScheduleUtil.pause(jobId); } catch (SchedulerException e) { throw new RuntimeException("创建定时任务失败"); } } /** * 暂停定时任务 **/ public static void pause(Long jobId) { try { scheduler.pauseJob(getJobKey(jobId)); } catch (SchedulerException e) { throw new RuntimeException("暂停定时任务失败"); } } /** * 恢复启动定时任务 **/ public static void resume(Long jobId) { try { scheduler.resumeJob(getJobKey(jobId)); } catch (SchedulerException e) { throw new RuntimeException("恢复启动定时任务失败"); } } /** * 更新启动定时任务 **/ public static void update(Long jobId, Job job) { try { TriggerKey triggerKey = getTriggerKey(jobId); // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCron()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 更新参数 trigger.getJobDataMap().put(JobConstant.JOB_MAP_KEY, job.getParams()); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } catch (SchedulerException e) { throw new RuntimeException("更新定时任务失败"); } } /** * 删除定时任务 **/ public static void delete(Long jobId) { try { scheduler.pauseTrigger(getTriggerKey(jobId)); scheduler.unscheduleJob(getTriggerKey(jobId)); scheduler.deleteJob(getJobKey(jobId)); } catch (SchedulerException e) { throw new RuntimeException("删除定时任务失败"); } } public static QuartzJobBean getJobClass(String classname) { return (QuartzJobBean) SpringContextUtil.getBean(classname); } public static JobKey getJobKey(Long jobId) { return JobKey.jobKey(JOB_KEY + jobId); } public static TriggerKey getTriggerKey(Long jobId) { return TriggerKey.triggerKey(JOB_KEY + jobId); }}1.1.8 编写controller类编写controller类,提供增删改的相关接口

@Slf4j@RestController@RequestMapping(value = "schedule/job")public class JobController { @Autowired private JobService jobService; /** * 添加定时任务 * @param job 任务 */ @PostMapping(value = "add") public R add(Job job) { jobService.createJob(job); return R.ok(null); } /** * 暂停定时任务 * @param id 任务ID */ @PostMapping(value = "pause/{id}") public R pause(@PathVariable Long id) { jobService.pauseJob(id); return R.ok(null); } /** * 恢复定时任务 * @param id 任务ID */ @PostMapping(value = "resume/{id}") public R resume(@PathVariable Long id) { jobService.resumeJob(id); return R.ok(null); } /** * 更新定时任务 * @param job 任务 */ @PostMapping(value = "update") public R update(Job job) { jobService.updateJob(job); return R.ok(null); } /** * 删除定时任务 * @param id 任务ID */ @PostMapping(value = "delete/{id}") public R delete(@PathVariable Long id) { jobService.deleteJob(id); return R.ok(null); }}1.1.9 编写service类@Servicepublic class JobServiceImpl extends ServiceImplJobMapper, Job implements JobService { @Transactional(rollbackFor = Exception.class) @Override public void createJob(Job job) { job.setStatus(JobConstant.JOB_STATUS_PAUSE); super.save(job); ScheduleUtil.create(job.getId(), job); } @Transactional(rollbackFor = Exception.class) @Override public void pauseJob(Long id) { Job job = this.checkJobExist(id); job.setStatus(JobConstant.JOB_STATUS_PAUSE); super.updateById(job); ScheduleUtil.pause(id); } @Transactional(rollbackFor = Exception.class) @Override public void resumeJob(Long id) { Job job = this.checkJobExist(id); job.setStatus(JobConstant.JOB_STATUS_RUNNING); super.updateById(job); ScheduleUtil.resume(id); } @Transactional(rollbackFor = Exception.class) @Override public void updateJob(Job job) { job.setStatus(JobConstant.JOB_STATUS_RUNNING); super.updateById(job); ScheduleUtil.update(job.getId(), job); } @Transactional(rollbackFor = Exception.class) @Override public void deleteJob(Long id) { super.removeById(id); ScheduleUtil.delete(id); } public Job checkJobExist(Long id) { Job job = super.getById(id); if (job == null) { throw new RuntimeException("不存在的任务ID"); } return job; }}1.1.10 测试基本代码已编写完成,开始测试。先使用postman工具调用添加定时任务的接口,新增之前编写的测试定时任务调度类的数据,设置每5秒执行一次,由于代码里写的逻辑是添加的时候只是创建好定时任务数据,并不会执行,如下图所示,成功创建数据。

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第1张图片

图1-1 调用添加接口

接着调用启动定时任务接口,再查看控制台输出,每5秒输出一次,证明定时任务调度成功。

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第2张图片

图1-2 调用启动接口

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第3张图片

图1-3 控制台输出

在调用暂停定时任务接口,查看控制台输出,发现已没有在输出,证明成功暂停定时任务调度。

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第4张图片

1.2 SpringBoot集成方式使用SpringBoot的集成方式,那两个核心的类就不需要写了,因为 spring-boot-starter-quartz 已经帮我们整理完成。所以就不需要我们手动写配置了,其集成步骤就变成:

pom文件添加依赖 ==》yml文件配置 ==》业务逻辑直接使用

1.2.1 添加pom依赖!--spring boot集成quartz定时任务--dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-quartz/artifactId/dependency1.2.2 yml文件配置上面介绍spring集成方式的时候quartz参数也是可以写在配置文件里的。

quartz: #相关属性配置 properties: org: quartz: scheduler: instanceName: JavaSjzlScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix: QRTZ_ isClustered: true clusterCheckinInterval: 10000 useProperties: false threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 threadPriority: 5 threadsInheritContextClassLoaderOfInitializingThread: true #数据库方式 job-store-type: jdbc1.2.3 业务逻辑直接使用与spring集成方式相比,springBoot集成方式是自动配置的,但是其他业务逻辑代码还是一样的,这里就不再啰嗦,可以直接使用上面的代码。把SchedulerConfig 配置类注释掉,重启项目就可以了。在调用新增接口,启动接口,查看控制台输出,每隔5秒成功输出。

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第5张图片

txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)-第6张图片

2、使用xxl-job框架关于使用xxl-job框架创建的方式我们下一篇文章在介绍。敬请期待!

结语

好了,以上就是今天要讲的内容,本文介绍了单机环境和分布式环境下,创建定时任务的几种方式。重点介绍了Spring集成Quartz框架,并持久化定时任务到数据库中。感谢大家的阅读,喜欢的朋友,欢迎点赞转发支持一下。

本次demo源码传送门:

Gitee:

Github:

本文网址:https://www.98ks.vip/knowledge-2194.html
转载请声明来自:98k源码网 - txupd.exe是什么文件(txupd.exe是什么文件夹可以删除吗)

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐