Quartz定时调度jar包的执行Demo分享
1.Quartz简介
 Quartz框架的核心是调度器。调度器负责管理Quartz应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。Quartz不仅仅是线程和线程管理。为确保可伸缩性,Quartz采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。这就是Quartz怎样能并发运行多个作业的原理。Quartz依赖一套松耦合的线程池管理部件来管理线程环境。
2.项目相关
 该定时器Demo用于定时执行制定路径下的jar包的编译,也可以用于普通的任务调度.通过对任务的查询修改删除来管理整个列表文件.可以通关开启和关闭来更改jar的开始执行状态(开启后如果需要停止只能关闭或重启服务器才能生效,具体的解决办法还在改进中).相关的一整套的UI界面比较简略,可以进行二次开发,主要整合了JPA的分页查询,可以查看相关代码部分.

3.测试路径
//主页路径:
http://localhost:9090/
//启动jar的路径(这里的我只是建了一个简单的springboot的helloword的Jar包,相关jar包在项目中可以找到)
http://localhost:8088/sayHello
4.代码相关
QuartzServiceImpl:
@Service
public class QuartzServiceImpl implements QuartzService {
    @Autowired
    private JobEntityRepository repository;
    @Override
    public JobEntity getById(int id) {
        return repository.getById(id);
    }
    //通过Id获取Job
    public JobEntity getJobEntityById(Integer id) {
        return repository.getById(id);
    }
    //从数据库中加载获取到所有Job
    public List<JobEntity> loadJobs() {
        List<JobEntity> list = new ArrayList<>();
        repository.findAll().forEach(list::add);
        return list;
    }
    //获取JobDataMap.(Job参数对象)
    public JobDataMap getJobDataMap(JobEntity job) {
        JobDataMap map = new JobDataMap();
        map.put("name", job.getName());
        map.put("group", job.getGroup());
        map.put("cronExpression", job.getCron());
        map.put("parameter", job.getParameter());
        map.put("JobDescription", job.getDescription());
        map.put("vmParam", job.getVmParam());
        map.put("jarPath", job.getJarPath());
        map.put("status", job.getStatus());
        return map;
    }
    //获取JobDetail,JobDetail是任务的定义,而Job是任务的执行逻辑,JobDetail里会引用一个Job Class来定义
    public JobDetail geJobDetail(JobKey jobKey, String description, JobDataMap map) {
        return JobBuilder.newJob(DynamicJob.class)
                .withIdentity(jobKey)
                .withDescription(description)
                .setJobData(map)
                .storeDurably()
                .build();
    }
    //获取Trigger (Job的触发器,执行规则)
    public Trigger getTrigger(JobEntity job) {
        return TriggerBuilder.newTrigger()
                .withIdentity(job.getName(), job.getGroup())
                .withSchedule(CronScheduleBuilder.cronSchedule(job.getCron()))
                .build();
    }
    //获取JobKey,包含Name和Group
    public JobKey getJobKey(JobEntity job) {
        return JobKey.jobKey(job.getName(), job.getGroup());
    }
}
DynamicJob:
/**
 * :@DisallowConcurrentExecution : 此标记用在实现Job的类上面,意思是不允许并发执行.
 * :注意org.quartz.threadPool.threadCount线程池中线程的数量至少要多个,否则@DisallowConcurrentExecution不生效
 * :假如Job的设置时间间隔为3秒,但Job执行时间是5秒,设置@DisallowConcurrentExecution以后程序会等任务执行完毕以后再去执行,否则会在3秒时再启用新的线程执行
 */
@DisallowConcurrentExecution
@PersistJobDataAfterExecution //没有异常就更新数据 可用?
@Component
@Slf4j
public class DynamicJob implements Job {
    private Logger logger = LoggerFactory.getLogger(DynamicJob.class);
    /**
     * 核心方法,Quartz Job真正的执行逻辑.
     *   executorContext JobExecutionContext中封装有Quartz运行所需要的所有信息
     * @throws JobExecutionException execute()方法只允许抛出JobExecutionException异常
     */
    @Override
    public void execute(JobExecutionContext executionContext) throws JobExecutionException {
        JobDataMap map = executionContext.getMergedJobDataMap();
        String jarPath = map.getString("jarPath");
        String parameter = map.getString("parameter");
        String vmParam = map.getString("vmParam");
        logger.info("Running Job name : {} ", map.getString("name"));
        logger.info("Running Job description : " + map.getString("JobDescription"));
        logger.info("Running Job group: {} ", map.getString("group"));
        logger.info("Running Job cron : " + map.getString("cronExpression"));
        logger.info("Running Job jar path : {} ", jarPath);
        logger.info("Running Job parameter : {} ", parameter);
        logger.info("Running Job vmParam : {} ", vmParam);
        long startTime = System.currentTimeMillis();
        if (!StringUtils.getStringUtil.isEmpty(jarPath)) {
            File jar = new File(jarPath);
            if (jar.exists()) {
                ProcessBuilder processBuilder = new ProcessBuilder();
                processBuilder.directory(jar.getParentFile());
                /**
                 * 这个是java的执行命令
                 * java -jar
                 */
                List<String> commands = new ArrayList<>();
                commands.add("java");
                if (!StringUtils.getStringUtil.isEmpty(vmParam)) {
                    commands.add(vmParam);
                }
                commands.add("-jar");
                commands.add(jarPath);
                commands.add(" &");
                System.out.println("commands->\n"+commands);
                if (!StringUtils.getStringUtil.isEmpty(parameter)) {
                    commands.add(parameter);
                    processBuilder.command(commands);
                    logger.info("Running Job details as follows >>>>>>>>>>>>>>>>>>>>: ");
                    logger.info("Running Job commands : {}  ", StringUtils.getStringUtil.getListString(commands));
                    try {
                        Process process = processBuilder.start();
                        logProcess(process.getInputStream(), process.getErrorStream());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new JobExecutionException("Job Jar not found >>  " + jarPath);
                }
                long endTime = System.currentTimeMillis();
                logger.info(">>>>>>>>>>>>> Running Job has been completed , cost time :  " + (endTime - startTime) + "ms\n");
            }
        }
    }
    //打印Job执行内容的日志
    private void logProcess(InputStream inputStream, InputStream errorStream) throws IOException {
        String inputLine;
        String errorLine;
        BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream));
        while ((inputLine = inputReader.readLine()) != null){
            logger.info(inputLine);
        }
        while ((errorLine = errorReader.readLine()) != null) {
            logger.error(errorLine);
        }
    }
}
5.项目git地址
(喜欢记得点星支持哦,谢谢!)
https://github.com/fengcharly/quartz-jpa
Quartz定时调度jar包的执行Demo分享的更多相关文章
- quartz 定时调度持久化数据库配置文件
		1 下载quartz对应版本jar包 2 初始化对应数据库sql(版本需要对应,不然会出现少字段的情况) ,下载地址 https://github.com/quartz-scheduler/quar ... 
- java 多线程——quartz 定时调度的例子
		java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ... 
- Quartz定时调度框架
		Quartz定时调度框架CronTrigger时间配置格式说明 CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年 ... 
- ASP.NET Core使用Quartz定时调度
		在应用程序开发过程中,经常会需要定时任务调度功能,本篇博客介绍Asp.net Core如何使用Quartz完成定时调度 一.Quartz使用步骤 创建调度器scheduler,并开启 创建Job作业 ... 
- java eclipse打jar包和执行jar中的main函数
		jar包使用eclipse打包步骤 右键需要打包的项目->选择Export 到这里有两种打包的方式 1.如果项目中没有使用其他第三方包等,则直接选择下图中的第一种即可(JAR file) 2.如 ... 
- Spring Quartz定时调度任务配置
		applicationContext-quartz.xml定时调度任务启动代码: <?xml version="1.0" encoding="UTF-8" ... 
- 原!!jar包 --可执行exe文件--安装包
		这几天由于部门统计名单,都是一边报,一边统计,感觉麻烦,写了个小工具,做成安装包.其他不多说,网上都有,我就自己按照网上操作,碰到了一些问题,对这些问题说下. ----------废话少说------ ... 
- 在IDEA中使用gradle配置打可执行jar包[可执行jar与其所依赖的jar分离]
		下面是我的项目的build.gradle文件的所有内容,注意高亮部分是关键: group 'com.xbs' version '1.0-SNAPSHOT' apply plugin: 'java' a ... 
- jar包双击执行引用外部包问题
		大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar包的程序入口. 具体的方法是修改jar包内目录META-INF下的MANIF ... 
随机推荐
- BNUOJ 3226 Godfather
			Godfather Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ... 
- 九度oj 题目1202:排序
			题目1202:排序 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:28802 解决:9408 题目描述: 对输入的n个数进行排序并输出. 输入: 输入的第一行包括一个整数n(1<=n ... 
- NYOJ-58最少步数,广搜思想!
			最少步数 时间限制:3000 ms | 内存限制:65535 KB 难度:4 -> Link <- 这个题深搜广搜都是可以的,迷宫已经给出了,就看怎么做了:一般起点终点确定用广搜 ... 
- python 安装依赖几个问题---HttpScan
			https://blog.csdn.net/chenggong2dm/article/details/61923420 https://www.cnblogs.com/caochuangui/p/59 ... 
- Java度线程——生产消费问题
			/*JDK1.4版本:生产者,消费者.多生产者,多消费者的问题.if判断标记,只有一次,会导致不该运行的线程运行了.出现了数据错误的情况.while判断标记,解决了线程获取执行权后,是否要运行! no ... 
- Spring Cloud(5):Hystrix的使用
			熔断:类似生活中的保险丝,电流过大就会熔断 降级:类似生活中的旅行,行李箱只有那么大,所以要抛弃一些非必需的物品 熔断降级应用: 某宝双十一商品下单,用户量巨大,于是考虑抛弃相关商品推荐等模块,确保该 ... 
- ETL增量单表同步简述_根据dateTime增量
			ETL增量单表同步简述 1. 实现需求 当原数据库的表有新增.更新.删除操作时,将改动数据同步到目标库对应的数据表. 2. 设计思路 设计总体流程图如下: 步骤简单说明: 1.设置job的执行属性,如 ... 
- docker: 通过docker方式安装jenkins
			1. docker pull jenkins 2. docker run -d -p 49001:8080 -v $PWD/jenkins:/var/jenkins_home:z -t jenkins ... 
- Zookeeper学习 & Paxos
			首先,Zookeeper是基于Paxos来进行分布式选举管理的,Paxos的内容可以参考我另一篇文章:http://www.cnblogs.com/charlesblc/p/6037004.html ... 
- 【c++】static_cast, dynamic_cast探讨
			C++类型转换分为:隐式类型转换和显式类型转换 一.隐式类型转换 1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型. ; d ... 
