Explorar el Código

系统:定时任务

4.0
郑根木 hace 2 años
padre
commit
d00342ce9c
Se han modificado 17 ficheros con 468 adiciones y 33 borrados
  1. +4
    -0
      smtweb-framework/bpm/pom.xml
  2. +6
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java
  3. +57
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/BaseJob.java
  4. +30
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobCache.java
  5. +81
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobEntity.java
  6. +102
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobLog.java
  7. +113
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobUtils.java
  8. +2
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java
  9. +34
    -0
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationClosedListener.java
  10. +2
    -0
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java
  11. +0
    -5
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java
  12. +13
    -2
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java
  13. +7
    -7
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java
  14. +3
    -0
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/IStartListener.java
  15. +9
    -12
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/BaseSysService.java
  16. +3
    -3
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java
  17. +2
    -2
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java

+ 4
- 0
smtweb-framework/bpm/pom.xml Ver fichero

@@ -35,6 +35,10 @@
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>[0.4, 0.5)</version>


+ 6
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java Ver fichero

@@ -26,6 +26,7 @@ public class BpmStartedListener implements IStartListener {
SwConsts.SysParam.RUN_PROJECTS = "bpm";
SysServiceFactory.getInstance().reg(new OneTimeTaskCleanService());
TreeHelper.regTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class);
}

@Override
@@ -36,4 +37,9 @@ public class BpmStartedListener implements IStartListener {
CacheManager.getIntance().init();
OneTimeServiceFactory.getInstance().start();
}

@Override
public void close() {
OneTimeServiceFactory.getInstance().stop();
}
}

+ 57
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/BaseJob.java Ver fichero

@@ -0,0 +1,57 @@
package cc.smtweb.system.bpm.web.sys.base.job;

import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.jdbc.ISimpleWorker;
import cc.smtweb.framework.core.systask.SingleRequestHelper;
import cc.smtweb.framework.core.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
* Created by Akmm at 2022-09-14 09:51
* 定时任务的基类
*/
@Slf4j
public abstract class BaseJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobEntity job = (JobEntity) jobExecutionContext.getJobDetail().getJobDataMap().get("job");

final String id = this.getClass().getName();
SingleRequestHelper.singleRequest(SwConsts.REDIS_KEY_BASE_JOB, id, job.getName() + "任务执行中,本次忽略.........", () -> {
JobLog jlog = startLog(job);
try {
String info = work();
endLog(jlog, true, info);
} catch (Exception e) {
endLog(jlog, false, e.getMessage());
log.error(job.getName() + ":::执行失败", e);
}

});
}

//任务执行信息,可返回执行结果
protected abstract String work();

//存任务日志-开始
private JobLog startLog(JobEntity job) {
JobLog jlog = new JobLog();
jlog.setId(DbEngine.getInstance().nextId());
jlog.setSjId(job.getId());
jlog.setBeginTime(DateUtil.nowDateTimeLong());
DbEngine.getInstance().doTransSingle(() -> DbEngine.getInstance().findDao(JobLog.class).insertEntity(jlog));
return jlog;
}

//存任务日志-结束
private void endLog(JobLog jlog, boolean sucess, String info) {
jlog.setEndTime(DateUtil.nowDateTimeLong());
jlog.setSuccess(sucess);
jlog.setInfo(info);
DbEngine.getInstance().doTransSingle(() -> DbEngine.getInstance().findDao(JobLog.class).updateEntity(jlog));
}
}

+ 30
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobCache.java Ver fichero

@@ -0,0 +1,30 @@
package cc.smtweb.system.bpm.web.sys.base.job;

import cc.smtweb.framework.core.annotation.SwCache;
import cc.smtweb.framework.core.cache.AbstractEntityCache;
import cc.smtweb.framework.core.cache.CacheManager;

/**
* Created by 1 at 2022-09-13 19:35:56
* 实体【[定时任务](SYS_JOB)】的缓存类
*/
@SwCache(ident = "SYS_JOB", title = "定时任务")
public class JobCache extends AbstractEntityCache<JobEntity> {
//缓存key:按编码
public final static String mk_code = "code";

public static JobCache getInstance() {
return CacheManager.getIntance().getCache(JobCache.class);
}

public JobCache() {
//缓存key:按编码
regMap(mk_code, "sj_code");
}

//缓存key:按编码
public final JobEntity getByCode(String key) {
return getByKey(mk_code, key);
}

}

+ 81
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobEntity.java Ver fichero

@@ -0,0 +1,81 @@
package cc.smtweb.system.bpm.web.sys.base.job;

import cc.smtweb.framework.core.annotation.SwTable;
import cc.smtweb.framework.core.db.impl.DefaultEntity;

/**
* Created by 1 at 2022-09-13 19:35:56
* 实体【[定时任务](SYS_JOB)】的Entity类
*/
@SwTable("SYS_JOB")
public class JobEntity extends DefaultEntity {
public static final String ENTITY_NAME = "SYS_JOB";

public JobEntity() {
super(ENTITY_NAME);
}

/** 主键 */
public long getId() {
return getLong("sj_id");
}

/** 主键 */
public void setId(long sj_id) {
put("sj_id", sj_id);
}
/** 编码 */
public String getCode() {
return getStr("sj_code");
}

/** 编码 */
public void setCode(String sj_code) {
put("sj_code", sj_code);
}
/** 名称 */
public String getName() {
return getStr("sj_name");
}

/** 名称 */
public void setName(String sj_name) {
put("sj_name", sj_name);
}
/** 执行类的路径 */
public String getExeClass() {
return getStr("sj_exe_class");
}

/** 执行类的路径 */
public void setExeClass(String sj_exe_class) {
put("sj_exe_class", sj_exe_class);
}
/** cron表达式 */
public String getCron() {
return getStr("sj_cron");
}

/** cron表达式 */
public void setCron(String sj_cron) {
put("sj_cron", sj_cron);
}
/** 是否启用 */
public boolean isEnable() {
return getBool("sj_enable");
}

/** 是否启用 */
public void setEnable(boolean sj_enable) {
setBool("sj_enable", sj_enable);
}
/** 备注 */
public String getRemark() {
return getStr("sj_remark");
}

/** 备注 */
public void setRemark(String sj_remark) {
put("sj_remark", sj_remark);
}
}

+ 102
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobLog.java Ver fichero

@@ -0,0 +1,102 @@
package cc.smtweb.system.bpm.web.sys.base.job;

import cc.smtweb.framework.core.annotation.SwTable;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.impl.DefaultEntity;

/**
* Created by 1 at 2022-09-14 10:09:03
* 实体【[定时任务执行日志](SYS_JOB_LOG)】的Entity类
*/
@SwTable("SYS_JOB_LOG")
public class JobLog extends DefaultEntity {
public static final String ENTITY_NAME = "SYS_JOB_LOG";

public JobLog() {
super(ENTITY_NAME);
}

/**
* 主键
*/
public long getId() {
return getLong("sjl_id");
}

/**
* 主键
*/
public void setId(long sjl_id) {
put("sjl_id", sjl_id);
}

/**
* 任务id
*/
public long getSjId() {
return getLong("sjl_sj_id");
}

/**
* 任务id
*/
public void setSjId(long sjl_sj_id) {
put("sjl_sj_id", sjl_sj_id);
}

/**
* 开始时间
*/
public long getBeginTime() {
return getLong("sjl_begin_time");
}

/**
* 开始时间
*/
public void setBeginTime(long sjl_begin_time) {
put("sjl_begin_time", sjl_begin_time);
}

/**
* 完成时间
*/
public long getEndTime() {
return getLong("sjl_end_time");
}

/**
* 完成时间
*/
public void setEndTime(long sjl_end_time) {
put("sjl_end_time", sjl_end_time);
}

/**
* 是否成功
*/
public boolean isSuccess() {
return getBool("sjl_success");
}

/**
* 是否成功
*/
public void setSuccess(boolean sjl_success) {
setBool("sjl_success", sjl_success);
}

/**
* 执行情况
*/
public String getInfo() {
return getStr("sjl_info");
}

/**
* 执行情况
*/
public void setInfo(String sjl_info) {
put("sjl_info", sjl_info);
}
}

+ 113
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobUtils.java Ver fichero

@@ -0,0 +1,113 @@
package cc.smtweb.system.bpm.web.sys.base.job;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.*;

/**
* Created by Akmm at 13-2-27 下午9:32
* 定时任务工厂
*/
@Slf4j
public class JobUtils {
private static Scheduler scheduler = null;
private static JobUtils instance = null;
private Map<String, JobEntity> mapJob = new HashMap<>();


public static Scheduler getScheduler() {
return scheduler;
}

public static JobUtils getInstance() {
if (instance == null) {
synchronized (JobUtils.class) {
if (instance == null) {
instance = new JobUtils();
}
}
}
return instance;
}

private JobUtils() {
try {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
scheduler = schedulerFactory.getScheduler();
} catch (Exception e) {
log.error("计划任务初始化失败", e);
e.printStackTrace();
}
}

//初始化所有任务
private void initJob() throws Exception {
Collection<JobEntity> list = JobCache.getInstance().getAll();
for (JobEntity job : list) {
if (job.isEnable()) {
addJob(job);
}
}

}

public void start() {
try {
clear();
if (!scheduler.isStarted()) scheduler.start();
initJob();
} catch (Exception e) {
log.error("计划任务开始失败", e);
e.printStackTrace();
}
}

public void stop() {
try {
if (!scheduler.isShutdown()) {
clear();
scheduler.shutdown();
}
} catch (Exception e) {
log.error("计划任务开始失败", e);
e.printStackTrace();
}
}

public void clear() throws SchedulerException {
for (JobEntity job : mapJob.values()) {
try {
deleteJob(job);
} catch (Exception e) {
log.debug("任务" + job.getId() + "删除失败!");
}
}
}

//添加任务
public synchronized void addJob(JobEntity job) throws Exception {
String jobId = String.valueOf(job.getId());
JobDetail jobDetail = JobBuilder.newJob((Class<? extends org.quartz.Job>) Class.forName(job.getExeClass()))
.withIdentity(jobId).build();
jobDetail.getJobDataMap().put("job", job);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobId)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCron()))
.build();

scheduler.scheduleJob(jobDetail, trigger);
}

//删除任务
public synchronized void deleteJob(JobEntity job) throws Exception {
String jobId = String.valueOf(job.getId());

scheduler.pauseTrigger(TriggerKey.triggerKey(jobId));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobId));
scheduler.deleteJob(JobKey.jobKey(jobId));
}
}

+ 2
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java Ver fichero

@@ -21,8 +21,8 @@ public class OneTimeTaskCleanService extends BaseSysService {
}

@Override
public void work() throws Exception {
public void work() {
String t = DateUtil.getNowYm() + "01000000";
DbEngine.getInstance().update("delete from " + EntityHelper.getSchemaTableName(OnetimeTask.ENTITY_NAME) + " where statu=? and create_time<?", OneTimeStatu.SUCCESS.value, t);
DbEngine.getInstance().update("delete from " + EntityHelper.getSchemaTableName(OnetimeTask.ENTITY_NAME) + " where sot_statu=? and sot_create_time<?", OneTimeStatu.SUCCESS.value, t);
}
}

+ 34
- 0
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationClosedListener.java Ver fichero

@@ -0,0 +1,34 @@
package cc.smtweb.framework.core;

import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.mvc.controller.IStartListener;
import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner;
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
import cc.smtweb.framework.core.systask.SysServiceFactory;
import cc.smtweb.framework.core.systask.WebStartedEvent;
import lombok.SneakyThrows;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;

/**
* 服务停止监听
*/
@Component
public class CoreApplicationClosedListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
SysServiceFactory.getInstance().stop();
List<IStartListener> list = BeanManager.getInstance().getStartListeners();
list.sort(Comparator.comparingInt(IStartListener::order));
for (IStartListener sl : list) {
sl.close();
}
}
}

+ 2
- 0
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java Ver fichero

@@ -4,6 +4,7 @@ import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.mvc.controller.IStartListener;
import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner;
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
import cc.smtweb.framework.core.systask.SysServiceFactory;
import cc.smtweb.framework.core.systask.WebStartedEvent;
import lombok.SneakyThrows;
import org.springframework.boot.context.event.ApplicationStartedEvent;
@@ -38,6 +39,7 @@ public class CoreApplicationStartedListener implements ApplicationListener<Appli
for (IStartListener sl : list) {
sl.run();
}
SysServiceFactory.getInstance().start();
// 通知 controller 正式使用
applicationContext.publishEvent(new WebStartedEvent());
SwConsts.SysParam.SYS_STARTED = true;


+ 0
- 5
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java Ver fichero

@@ -37,9 +37,4 @@ public class CoreAutoConfiguration implements WebMvcConfigurer {
public ControllerConfig coreControllerConfig() {
return new ControllerConfig("core", "cc.smtweb.framework.core");
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CoreInterceptor());
}
}

+ 13
- 2
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java Ver fichero

@@ -356,7 +356,7 @@ public class JdbcEngine {
}

//独立事务
public void doTransSingle(IDbWorker worker) throws Exception {
public void doTransSingle(IDbWorker worker) throws SwException {
JdbcTrans jdbcTrans = openTrans();
try {
worker.work();
@@ -364,11 +364,22 @@ public class JdbcEngine {
} catch (Exception e) {
jdbcTrans.rollback();
worker.doAfterDbRollback();
throw e;
throw new SwException(e);
}
worker.doAfterDbCommit();
}

public void doTransSingle(ISimpleWorker worker) throws SwException {
JdbcTrans jdbcTrans = openTrans();
try {
worker.work();
jdbcTrans.commit();
} catch (Exception e) {
jdbcTrans.rollback();
throw new SwException(e);
}
}


/**
* 获取原始数据库连接执行命令


+ 7
- 7
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java Ver fichero

@@ -1,5 +1,6 @@
package cc.smtweb.framework.core.mvc.config;

import cc.smtweb.framework.core.CoreInterceptor;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.cache.redis.RedisManager;
import cc.smtweb.framework.core.db.jdbc.IdGenerator;
@@ -19,10 +20,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.*;

import java.util.List;

@@ -49,9 +47,6 @@ public class WebMvcConfig implements WebMvcConfigurer {

private static final String TRUE_VALUE = "true";

@Autowired
private RedisManager redisManager;

@Bean
public SessionManager sessionManager(RedisManager redisManager, IdGenerator idGenerator) {
return new SessionManager(redisManager, idGenerator);
@@ -68,6 +63,11 @@ public class WebMvcConfig implements WebMvcConfigurer {
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CoreInterceptor());
}

@Override
public void addCorsMappings(CorsRegistry registry) {
// 2.4 以前使用 .allowedOrigins("*")
registry.addMapping("/**")


+ 3
- 0
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/IStartListener.java Ver fichero

@@ -13,4 +13,7 @@ public interface IStartListener {

//启动事件
void run();

//服务停止时
default void close(){}
}

+ 9
- 12
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/BaseSysService.java Ver fichero

@@ -23,17 +23,14 @@ public abstract class BaseSysService implements Runnable {
public void run() {
try {
final String id = this.getClass().getName();
SingleRequestHelper.singleRequest(SwConsts.REDIS_KEY_BASE_JOB, id, "任务执行中,本次忽略.........", new SingleRequestHelper.ISingleWork() {
@Override
public void doSingleWork() throws Exception {
long time = System.currentTimeMillis();
if (isPrintLog()) {
log.debug(getTitle() + ":::开始执行.........");
}
work();
if (isPrintLog()) {
log.debug(getTitle() + ":::执行完成,耗时:" + (System.currentTimeMillis() - time) + "毫秒.........");
}
SingleRequestHelper.singleRequest(SwConsts.REDIS_KEY_BASE_JOB, id, "任务执行中,本次忽略.........", () -> {
long time = System.currentTimeMillis();
if (isPrintLog()) {
log.debug(getTitle() + ":::开始执行.........");
}
work();
if (isPrintLog()) {
log.debug(getTitle() + ":::执行完成,耗时:" + (System.currentTimeMillis() - time) + "毫秒.........");
}
});
} catch (Exception e) {
@@ -42,5 +39,5 @@ public abstract class BaseSysService implements Runnable {
}

//主要要干的活
protected abstract void work() throws Exception;
protected abstract void work();
}

+ 3
- 3
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java Ver fichero

@@ -8,15 +8,15 @@ import cc.smtweb.framework.core.util.StringUtil;
public class SingleRequestHelper {

public static interface ISingleWork {
void doSingleWork() throws Exception;
void doSingleWork();

}

public static void singleRequest(String region_key, String key, ISingleWork singleWork) throws Exception {
public static void singleRequest(String region_key, String key, ISingleWork singleWork) {
singleRequest(region_key, key, "其他人正在执行该操作,请等待!", singleWork);
}

public static void singleRequest(String region_key, String key, String tip_msg, ISingleWork singleWork) throws Exception {
public static void singleRequest(String region_key, String key, String tip_msg, ISingleWork singleWork) {
boolean clearCache = false;
try {
String lastTime = RedisManager.getInstance().hGet(region_key, key, String.class);


+ 2
- 2
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java Ver fichero

@@ -39,7 +39,7 @@ public class SysServiceFactory {


//启动任务
protected void start() {
public void start() {
if (schedule != null) {
stop();
}
@@ -52,7 +52,7 @@ public class SysServiceFactory {
}

//停止任务
protected void stop() {
public void stop() {
schedule.shutdown();
}
}

Cargando…
Cancelar
Guardar