├── .gitignore ├── README.md ├── db └── init.sql ├── pom.xml ├── scheduler-admin ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── yueshuo │ │ │ └── scheduler │ │ │ └── admin │ │ │ ├── SchedulerAdminApplication.java │ │ │ ├── controller │ │ │ ├── IndexController.java │ │ │ ├── JobApiController.java │ │ │ ├── JobCodeController.java │ │ │ ├── JobDagController.java │ │ │ ├── JobGroupController.java │ │ │ ├── JobInfoController.java │ │ │ ├── JobLogController.java │ │ │ ├── UserController.java │ │ │ ├── annotation │ │ │ │ └── PermissionLimit.java │ │ │ ├── interceptor │ │ │ │ ├── CookieInterceptor.java │ │ │ │ ├── PermissionInterceptor.java │ │ │ │ └── WebMvcConfig.java │ │ │ ├── resolver │ │ │ │ └── WebExceptionResolver.java │ │ │ └── websocket │ │ │ │ ├── WSLogController.java │ │ │ │ ├── WSStatusController.java │ │ │ │ └── WebSocketConfig.java │ │ │ ├── core │ │ │ ├── alarm │ │ │ │ ├── JobAlarm.java │ │ │ │ ├── JobAlarmer.java │ │ │ │ └── impl │ │ │ │ │ └── EmailJobAlarm.java │ │ │ ├── complete │ │ │ │ └── XxlJobCompleter.java │ │ │ ├── conf │ │ │ │ └── XxlJobAdminConfig.java │ │ │ ├── cron │ │ │ │ └── CronExpression.java │ │ │ ├── dag │ │ │ │ ├── DAGExecutorBlockStrategyEnum.java │ │ │ │ ├── DAGJobUtils.java │ │ │ │ ├── DAGQueueMgr.java │ │ │ │ ├── DAGRunRecordCacheUtils.java │ │ │ │ └── DAGTaskHandlerHelper.java │ │ │ ├── exception │ │ │ │ └── XxlJobException.java │ │ │ ├── log │ │ │ │ ├── JobStatusThread.java │ │ │ │ ├── SchedulerLogger.java │ │ │ │ └── TailLogThread.java │ │ │ ├── model │ │ │ │ ├── PstDagJobInfo.java │ │ │ │ ├── PstDagJobRunRecordInfo.java │ │ │ │ ├── XxlJobGroup.java │ │ │ │ ├── XxlJobInfo.java │ │ │ │ ├── XxlJobLog.java │ │ │ │ ├── XxlJobLogGlue.java │ │ │ │ ├── XxlJobLogReport.java │ │ │ │ ├── XxlJobRegistry.java │ │ │ │ └── XxlJobUser.java │ │ │ ├── old │ │ │ │ ├── RemoteHttpJobBean.java │ │ │ │ ├── XxlJobDynamicScheduler.java │ │ │ │ └── XxlJobThreadPool.java │ │ │ ├── route │ │ │ │ ├── ExecutorRouteStrategyEnum.java │ │ │ │ ├── ExecutorRouter.java │ │ │ │ └── strategy │ │ │ │ │ ├── ExecutorRouteBusyover.java │ │ │ │ │ ├── ExecutorRouteConsistentHash.java │ │ │ │ │ ├── ExecutorRouteFailover.java │ │ │ │ │ ├── ExecutorRouteFirst.java │ │ │ │ │ ├── ExecutorRouteLFU.java │ │ │ │ │ ├── ExecutorRouteLRU.java │ │ │ │ │ ├── ExecutorRouteLast.java │ │ │ │ │ ├── ExecutorRouteRandom.java │ │ │ │ │ └── ExecutorRouteRound.java │ │ │ ├── scheduler │ │ │ │ ├── MisfireStrategyEnum.java │ │ │ │ ├── ScheduleTypeEnum.java │ │ │ │ └── XxlJobScheduler.java │ │ │ ├── thread │ │ │ │ ├── DAGJobScheduleHelper.java │ │ │ │ ├── JobCompleteHelper.java │ │ │ │ ├── JobFailMonitorHelper.java │ │ │ │ ├── JobLogReportHelper.java │ │ │ │ ├── JobRegistryHelper.java │ │ │ │ ├── JobScheduleHelper.java │ │ │ │ └── JobTriggerPoolHelper.java │ │ │ ├── trigger │ │ │ │ ├── TriggerTypeEnum.java │ │ │ │ └── XxlJobTrigger.java │ │ │ └── util │ │ │ │ ├── BeanCopyUtils.java │ │ │ │ ├── CookieUtil.java │ │ │ │ ├── FtlUtil.java │ │ │ │ ├── I18nUtil.java │ │ │ │ ├── JacksonUtil.java │ │ │ │ └── LocalCacheUtil.java │ │ │ ├── dao │ │ │ ├── PstDagJobInfoDao.java │ │ │ ├── PstDagJobRunRecordDao.java │ │ │ ├── XxlJobGroupDao.java │ │ │ ├── XxlJobInfoDao.java │ │ │ ├── XxlJobLogDao.java │ │ │ ├── XxlJobLogGlueDao.java │ │ │ ├── XxlJobLogReportDao.java │ │ │ ├── XxlJobRegistryDao.java │ │ │ └── XxlJobUserDao.java │ │ │ ├── service │ │ │ ├── LoginService.java │ │ │ ├── PstDagJobRunRecordService.java │ │ │ ├── PstDagJobService.java │ │ │ ├── XxlJobService.java │ │ │ └── impl │ │ │ │ ├── AdminBizImpl.java │ │ │ │ ├── PstDagJobRunRecordServiceImpl.java │ │ │ │ ├── PstDagJobServiceImpl.java │ │ │ │ └── XxlJobServiceImpl.java │ │ │ └── vo │ │ │ ├── DAGJobInfoVO.java │ │ │ ├── Edge.java │ │ │ ├── JobDagInfoVO.java │ │ │ └── Node.java │ └── resources │ │ ├── application.properties │ │ ├── i18n │ │ ├── message_en.properties │ │ ├── message_zh_CN.properties │ │ └── message_zh_TC.properties │ │ ├── logback.xml │ │ ├── mybatis-mapper │ │ ├── PstDagJobInfoMapper.xml │ │ ├── PstDagJobRunRecordMapper.xml │ │ ├── XxlJobGroupMapper.xml │ │ ├── XxlJobInfoMapper.xml │ │ ├── XxlJobLogGlueMapper.xml │ │ ├── XxlJobLogMapper.xml │ │ ├── XxlJobLogReportMapper.xml │ │ ├── XxlJobRegistryMapper.xml │ │ └── XxlJobUserMapper.xml │ │ ├── static │ │ ├── adminlte │ │ │ ├── bower_components │ │ │ │ ├── Ionicons │ │ │ │ │ ├── css │ │ │ │ │ │ └── ionicons.min.css │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── ionicons.eot │ │ │ │ │ │ ├── ionicons.svg │ │ │ │ │ │ ├── ionicons.ttf │ │ │ │ │ │ └── ionicons.woff │ │ │ │ ├── PACE │ │ │ │ │ ├── pace.min.js │ │ │ │ │ └── themes │ │ │ │ │ │ └── blue │ │ │ │ │ │ └── pace-theme-flash.css │ │ │ │ ├── bootstrap-daterangepicker │ │ │ │ │ ├── daterangepicker.css │ │ │ │ │ └── daterangepicker.js │ │ │ │ ├── bootstrap │ │ │ │ │ ├── css │ │ │ │ │ │ ├── bootstrap.min.css │ │ │ │ │ │ └── bootstrap.min.css.map │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ │ └── js │ │ │ │ │ │ └── bootstrap.min.js │ │ │ │ ├── datatables.net-bs │ │ │ │ │ ├── css │ │ │ │ │ │ └── dataTables.bootstrap.min.css │ │ │ │ │ └── js │ │ │ │ │ │ └── dataTables.bootstrap.min.js │ │ │ │ ├── datatables.net │ │ │ │ │ └── js │ │ │ │ │ │ └── jquery.dataTables.min.js │ │ │ │ ├── fastclick │ │ │ │ │ └── fastclick.js │ │ │ │ ├── font-awesome │ │ │ │ │ ├── css │ │ │ │ │ │ ├── font-awesome.css.map │ │ │ │ │ │ └── font-awesome.min.css │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ ├── jquery-slimscroll │ │ │ │ │ └── jquery.slimscroll.min.js │ │ │ │ ├── jquery │ │ │ │ │ └── jquery.min.js │ │ │ │ └── moment │ │ │ │ │ └── moment.min.js │ │ │ ├── dist │ │ │ │ ├── css │ │ │ │ │ ├── AdminLTE.min.css │ │ │ │ │ └── skins │ │ │ │ │ │ └── _all-skins.min.css │ │ │ │ └── js │ │ │ │ │ └── adminlte.min.js │ │ │ └── plugins │ │ │ │ └── iCheck │ │ │ │ ├── icheck.min.js │ │ │ │ └── square │ │ │ │ ├── blue.css │ │ │ │ ├── blue.png │ │ │ │ └── blue@2x.png │ │ ├── css │ │ │ └── dag-index.css │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── end.svg │ │ │ ├── error.svg │ │ │ ├── ok.svg │ │ │ ├── runing.svg │ │ │ ├── start.svg │ │ │ ├── task.svg │ │ │ ├── 完成.png │ │ │ ├── 开始.png │ │ │ ├── 结束.png │ │ │ ├── 进度.png │ │ │ ├── 进行中.png │ │ │ └── 错误.png │ │ ├── js │ │ │ ├── common.1.js │ │ │ ├── index.js │ │ │ ├── jobcode.index.1.js │ │ │ ├── jobdag.detail.1.js │ │ │ ├── jobdag.index.1.js │ │ │ ├── jobgroup.index.1.js │ │ │ ├── jobinfo.index.1.js │ │ │ ├── joblog.detail.1.js │ │ │ ├── joblog.index.1.js │ │ │ ├── login.1.js │ │ │ ├── plugins │ │ │ │ ├── d3-transform.min.js │ │ │ │ ├── d3.min.js │ │ │ │ ├── d3.v5.min.js │ │ │ │ └── jquery-ui.min.js │ │ │ └── user.index.1.js │ │ └── plugins │ │ │ ├── codemirror │ │ │ ├── addon │ │ │ │ └── hint │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ ├── show-hint.css │ │ │ │ │ └── show-hint.js │ │ │ ├── lib │ │ │ │ ├── codemirror.css │ │ │ │ └── codemirror.js │ │ │ └── mode │ │ │ │ ├── clike │ │ │ │ └── clike.js │ │ │ │ ├── javascript │ │ │ │ └── javascript.js │ │ │ │ ├── php │ │ │ │ └── php.js │ │ │ │ ├── powershell │ │ │ │ └── powershell.js │ │ │ │ ├── python │ │ │ │ └── python.js │ │ │ │ └── shell │ │ │ │ └── shell.js │ │ │ ├── cronGen │ │ │ ├── cronGen.js │ │ │ └── cronGen_en.js │ │ │ ├── doublebox │ │ │ ├── doublebox-bootstrap.css │ │ │ └── doublebox-bootstrap.js │ │ │ ├── echarts │ │ │ └── echarts.common.min.js │ │ │ ├── jquery │ │ │ ├── jquery.cookie.js │ │ │ └── jquery.validate.min.js │ │ │ └── layer │ │ │ ├── layer.js │ │ │ └── theme │ │ │ └── default │ │ │ ├── icon-ext.png │ │ │ ├── icon.png │ │ │ ├── layer.css │ │ │ ├── loading-0.gif │ │ │ ├── loading-1.gif │ │ │ └── loading-2.gif │ │ └── templates │ │ ├── common │ │ ├── common.exception.ftl │ │ └── common.macro.ftl │ │ ├── help.ftl │ │ ├── index.ftl │ │ ├── jobcode │ │ └── jobcode.index.ftl │ │ ├── jobdag │ │ ├── jobdag.detail.ftl │ │ ├── jobdag.index.ftl │ │ └── jobdag.view.ftl │ │ ├── jobgroup │ │ └── jobgroup.index.ftl │ │ ├── jobinfo │ │ └── jobinfo.index.ftl │ │ ├── joblog │ │ ├── joblog.detail-dialog.ftl │ │ ├── joblog.detail.ftl │ │ ├── joblog.index-dialog.ftl │ │ └── joblog.index.ftl │ │ ├── login.ftl │ │ └── user │ │ └── user.index.ftl │ └── test │ └── java │ └── com │ ├── xxl │ └── job │ │ ├── adminbiz │ │ └── AdminBizTest.java │ │ └── executorbiz │ │ └── ExecutorBizTest.java │ └── yueshuo │ └── scheduler │ └── admin │ ├── controller │ ├── AbstractSpringMvcTest.java │ └── JobInfoControllerTest.java │ ├── core │ └── util │ │ └── JacksonUtilTest.java │ ├── dao │ ├── XxlJobGroupDaoTest.java │ ├── XxlJobInfoDaoTest.java │ ├── XxlJobLogDaoTest.java │ ├── XxlJobLogGlueDaoTest.java │ └── XxlJobRegistryDaoTest.java │ └── util │ └── I18nUtilTest.java ├── scheduler-core ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── yueshuo │ └── scheduler │ └── core │ ├── biz │ ├── AdminBiz.java │ ├── ExecutorBiz.java │ ├── client │ │ ├── AdminBizClient.java │ │ └── ExecutorBizClient.java │ ├── impl │ │ └── ExecutorBizImpl.java │ └── model │ │ ├── HandleCallbackParam.java │ │ ├── IdleBeatParam.java │ │ ├── KillParam.java │ │ ├── LogParam.java │ │ ├── LogResult.java │ │ ├── RegistryParam.java │ │ ├── ReturnT.java │ │ └── TriggerParam.java │ ├── context │ ├── XxlJobContext.java │ └── XxlJobHelper.java │ ├── enums │ ├── ExecutorBlockStrategyEnum.java │ └── RegistryConfig.java │ ├── executor │ ├── XxlJobExecutor.java │ └── impl │ │ ├── XxlJobSimpleExecutor.java │ │ └── XxlJobSpringExecutor.java │ ├── glue │ ├── GlueFactory.java │ ├── GlueTypeEnum.java │ └── impl │ │ └── SpringGlueFactory.java │ ├── handler │ ├── IJobHandler.java │ ├── annotation │ │ ├── JobHandler.java │ │ └── XxlJob.java │ └── impl │ │ ├── GlueJobHandler.java │ │ ├── MethodJobHandler.java │ │ └── ScriptJobHandler.java │ ├── log │ └── XxlJobFileAppender.java │ ├── server │ └── EmbedServer.java │ ├── thread │ ├── ExecutorRegistryThread.java │ ├── JobLogFileCleanThread.java │ ├── JobThread.java │ └── TriggerCallbackThread.java │ └── util │ ├── DateUtil.java │ ├── FileUtil.java │ ├── GsonTool.java │ ├── IpUtil.java │ ├── JdkSerializeTool.java │ ├── NetUtil.java │ ├── ScriptUtil.java │ ├── ShardingUtil.java │ ├── ThrowableUtil.java │ └── XxlJobRemotingUtil.java └── scheduler-executor ├── java-sample ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── yueshuo │ │ │ └── scheduler │ │ │ └── executor │ │ │ ├── ExecutorApplication.java │ │ │ ├── config │ │ │ └── ExecutorConfig.java │ │ │ ├── service │ │ │ └── JobServiceExample.java │ │ │ └── utils │ │ │ ├── DBUtil.java │ │ │ ├── mysql │ │ │ └── MySqlDataHelper.java │ │ │ └── postgresql │ │ │ └── PGDataHelper.java │ └── resources │ │ ├── application.properties │ │ └── logback.xml │ └── test │ └── java │ └── com │ └── yueshuo │ └── scheduler │ └── executor │ └── test │ └── XxlJobExecutorExampleBootApplicationTests.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /temp 3 | **/target 4 | **/target/** 5 | **/logs 6 | **/*.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # task-schedule 2 | 在xxl job 的基础上 增加任务dag调度 3 | 4 | 相关详情请查看原作者项目 [xxl-job](https://www.xuxueli.com.yueshuo.scheduler/) 5 | 6 | # 其他 7 | 本项目基于xxl-job进行修改,如有侵权请联系 [邮箱:yygqn7@163.com](yygqn7@163.com) 进行删除 8 | -------------------------------------------------------------------------------- /scheduler-admin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-slim 2 | MAINTAINER JayTan 3 | 4 | ENV PARAMS="" 5 | 6 | ENV TZ=PRC 7 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 8 | 9 | ADD target/xxl-job-admin-*.jar /app.jar 10 | 11 | ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"] -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/SchedulerAdminApplication.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author xuxueli 2018-10-28 00:38:13 8 | */ 9 | @SpringBootApplication 10 | public class SchedulerAdminApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(SchedulerAdminApplication.class, args); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/annotation/PermissionLimit.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.annotation; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 权限限制 11 | * @author xuxueli 2015-12-12 18:29:02 12 | */ 13 | @Target(ElementType.METHOD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface PermissionLimit { 16 | 17 | /** 18 | * 登录拦截 (默认拦截) 19 | */ 20 | boolean limit() default true; 21 | 22 | /** 23 | * 要求管理员权限 24 | * 25 | * @return 26 | */ 27 | boolean adminuser() default false; 28 | 29 | } -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/interceptor/CookieInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.interceptor; 2 | 3 | import com.yueshuo.scheduler.admin.core.util.FtlUtil; 4 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.ModelAndView; 7 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 8 | 9 | import javax.servlet.http.Cookie; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.util.HashMap; 13 | 14 | /** 15 | * push cookies to model as cookieMap 16 | * 17 | * @author xuxueli 2015-12-12 18:09:04 18 | */ 19 | @Component 20 | public class CookieInterceptor extends HandlerInterceptorAdapter { 21 | 22 | @Override 23 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 24 | ModelAndView modelAndView) throws Exception { 25 | 26 | // cookie 27 | if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) { 28 | HashMap cookieMap = new HashMap(); 29 | for (Cookie ck : request.getCookies()) { 30 | cookieMap.put(ck.getName(), ck); 31 | } 32 | modelAndView.addObject("cookieMap", cookieMap); 33 | } 34 | 35 | // static method 36 | if (modelAndView != null) { 37 | modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); 38 | } 39 | 40 | super.postHandle(request, response, handler, modelAndView); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/interceptor/PermissionInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.interceptor; 2 | 3 | import com.yueshuo.scheduler.admin.controller.annotation.PermissionLimit; 4 | import com.yueshuo.scheduler.admin.core.model.XxlJobUser; 5 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 6 | import com.yueshuo.scheduler.admin.service.LoginService; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.web.method.HandlerMethod; 9 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | 15 | /** 16 | * 权限拦截 17 | * 18 | * @author xuxueli 2015-12-12 18:09:04 19 | */ 20 | @Component 21 | public class PermissionInterceptor extends HandlerInterceptorAdapter { 22 | 23 | @Resource 24 | private LoginService loginService; 25 | 26 | @Override 27 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 28 | 29 | if (!(handler instanceof HandlerMethod)) { 30 | return super.preHandle(request, response, handler); 31 | } 32 | 33 | // if need login 34 | boolean needLogin = true; 35 | boolean needAdminuser = false; 36 | HandlerMethod method = (HandlerMethod)handler; 37 | PermissionLimit permission = method.getMethodAnnotation(PermissionLimit.class); 38 | if (permission!=null) { 39 | needLogin = permission.limit(); 40 | needAdminuser = permission.adminuser(); 41 | } 42 | 43 | if (needLogin) { 44 | XxlJobUser loginUser = loginService.ifLogin(request, response); 45 | if (loginUser == null) { 46 | response.setStatus(302); 47 | response.setHeader("location", request.getContextPath()+"/toLogin"); 48 | return false; 49 | } 50 | if (needAdminuser && loginUser.getRole()!=1) { 51 | throw new RuntimeException(I18nUtil.getString("system_permission_limit")); 52 | } 53 | request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); 54 | } 55 | 56 | return super.preHandle(request, response, handler); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/interceptor/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.interceptor; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | import javax.annotation.Resource; 8 | 9 | /** 10 | * web mvc config 11 | * 12 | * @author xuxueli 2018-04-02 20:48:20 13 | */ 14 | @Configuration 15 | public class WebMvcConfig implements WebMvcConfigurer { 16 | 17 | @Resource 18 | private PermissionInterceptor permissionInterceptor; 19 | @Resource 20 | private CookieInterceptor cookieInterceptor; 21 | 22 | @Override 23 | public void addInterceptors(InterceptorRegistry registry) { 24 | registry.addInterceptor(permissionInterceptor).addPathPatterns("/**"); 25 | registry.addInterceptor(cookieInterceptor).addPathPatterns("/**"); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/resolver/WebExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.resolver; 2 | 3 | import com.yueshuo.scheduler.admin.core.exception.XxlJobException; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.admin.core.util.JacksonUtil; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.method.HandlerMethod; 11 | import org.springframework.web.servlet.HandlerExceptionResolver; 12 | import org.springframework.web.servlet.ModelAndView; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | /** 19 | * common exception resolver 20 | * 21 | * @author xuxueli 2016-1-6 19:22:18 22 | */ 23 | @Component 24 | public class WebExceptionResolver implements HandlerExceptionResolver { 25 | private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class); 26 | 27 | @Override 28 | public ModelAndView resolveException(HttpServletRequest request, 29 | HttpServletResponse response, Object handler, Exception ex) { 30 | 31 | if (!(ex instanceof XxlJobException)) { 32 | logger.error("WebExceptionResolver:{}", ex); 33 | } 34 | 35 | // if json 36 | boolean isJson = false; 37 | if (handler instanceof HandlerMethod) { 38 | HandlerMethod method = (HandlerMethod)handler; 39 | ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); 40 | if (responseBody != null) { 41 | isJson = true; 42 | } 43 | } 44 | 45 | // error result 46 | ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
")); 47 | 48 | // response 49 | ModelAndView mv = new ModelAndView(); 50 | if (isJson) { 51 | try { 52 | response.setContentType("application/json;charset=utf-8"); 53 | response.getWriter().print(JacksonUtil.writeValueAsString(errorResult)); 54 | } catch (IOException e) { 55 | logger.error(e.getMessage(), e); 56 | } 57 | return mv; 58 | } else { 59 | 60 | mv.addObject("exceptionMsg", errorResult.getMsg()); 61 | mv.setViewName("/common/common.exception"); 62 | return mv; 63 | } 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/websocket/WSLogController.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.websocket; 2 | 3 | import com.yueshuo.scheduler.admin.core.log.TailLogThread; 4 | import com.yueshuo.scheduler.core.util.DateUtil; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.websocket.OnClose; 10 | import javax.websocket.OnError; 11 | import javax.websocket.OnOpen; 12 | import javax.websocket.Session; 13 | import javax.websocket.server.PathParam; 14 | import javax.websocket.server.ServerEndpoint; 15 | import java.io.FileInputStream; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.util.Date; 19 | import java.util.concurrent.ExecutorService; 20 | import java.util.concurrent.Executors; 21 | 22 | /** 23 | * @Author: TheBigBlue 24 | * @Description: 向web端实时推送信息 25 | * @Date: 2019/7/16 26 | **/ 27 | @Component 28 | @ServerEndpoint(value = "/ws/logs/{dagJobId}") 29 | public class WSLogController { 30 | 31 | private static final Logger LOGGER = LoggerFactory.getLogger(WSLogController.class); 32 | 33 | private ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 34 | 35 | private Process process; 36 | private InputStream inputStream; 37 | 38 | /** 39 | * 新的WebSocket请求开启 40 | */ 41 | @OnOpen 42 | public void onOpen(@PathParam("dagJobId") String jobId, Session session) { 43 | 44 | LOGGER.info("[{}]加入连接!", jobId); 45 | try { 46 | String dateStr = DateUtil.format(new Date(),"yyyyMMdd"); 47 | String filePath = new StringBuilder(System.getProperty("user.dir")).append("/logs/").append(dateStr).append("/").append(jobId).append(".log").toString(); 48 | // 执行tail -f命令,由于是tail命令,需要在linux系统执行 49 | // process = Runtime.getRuntime().exec("tail -f " + filePath); 50 | // inputStream = process.getInputStream(); 51 | inputStream = new FileInputStream(filePath); 52 | // 一定要启动新的线程,防止InputStream阻塞处理WebSocket的线程 53 | pool.submit(new TailLogThread(inputStream, session)); 54 | // new TailLogThread(inputStream, session).start(); 55 | } catch (IOException e) { 56 | LOGGER.error("[{}]获取日志内容失败。", jobId, e); 57 | onClose(jobId); 58 | } 59 | } 60 | 61 | /** 62 | * WebSocket请求关闭 63 | */ 64 | @OnClose 65 | public void onClose(@PathParam("jobId") String jobId) { 66 | LOGGER.info("[" + jobId + "]断开连接!"); 67 | try { 68 | if (inputStream != null) 69 | inputStream.close(); 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } 73 | if (process != null) 74 | process.destroy(); 75 | } 76 | 77 | @OnError 78 | public void onError(Session session, Throwable thr) { 79 | try { 80 | session.close(); 81 | } catch (IOException e) { 82 | e.printStackTrace(); 83 | } 84 | thr.printStackTrace(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/websocket/WSStatusController.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.websocket; 2 | 3 | import com.yueshuo.scheduler.admin.core.conf.XxlJobAdminConfig; 4 | import com.yueshuo.scheduler.admin.core.log.JobStatusThread; 5 | import com.yueshuo.scheduler.admin.core.model.PstDagJobInfo; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.websocket.*; 11 | import javax.websocket.server.PathParam; 12 | import javax.websocket.server.ServerEndpoint; 13 | import java.io.IOException; 14 | import java.util.concurrent.ExecutorService; 15 | import java.util.concurrent.Executors; 16 | 17 | /** 18 | * @Author: TheBigBlue 19 | * @Description: 向web端实时推送信息 20 | * @Date: 2019/7/16 21 | **/ 22 | @Component 23 | @ServerEndpoint(value = "/ws/status/{dagJobId}/{recordTime}") 24 | public class WSStatusController { 25 | 26 | private static final Logger LOGGER = LoggerFactory.getLogger(WSStatusController.class); 27 | 28 | private ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 29 | 30 | private Process process; 31 | 32 | /** 33 | * 新的WebSocket请求开启 34 | */ 35 | @OnOpen 36 | public void onOpen(@PathParam("dagJobId") String jobId,@PathParam("recordTime") long recordTime, Session session) { 37 | LOGGER.info("[{}-{}]加入连接!", jobId,recordTime); 38 | try { 39 | PstDagJobInfo dagJobInfo = XxlJobAdminConfig.getAdminConfig().getDagJobInfoDao().loadById(Long.parseLong(jobId)) ; 40 | pool.submit(new JobStatusThread(dagJobInfo,recordTime, session)); 41 | } catch (Exception e) { 42 | LOGGER.error("[{}-{}]获取状态内容失败。", jobId,recordTime, e); 43 | } 44 | } 45 | 46 | /** 47 | * WebSocket请求关闭 48 | */ 49 | @OnClose 50 | public void onClose(@PathParam("dagJobId") String jobId,@PathParam("recordTime") long recordTime, Session session) { 51 | LOGGER.info("[" + jobId + "]-{} 断开连接!",recordTime); 52 | try { 53 | session.close(); 54 | } catch (Exception e) { 55 | LOGGER.info("关闭 websocket 连接异常 ",e); 56 | } 57 | if (process != null){ 58 | process.destroy(); 59 | } 60 | 61 | } 62 | 63 | @OnMessage 64 | public void onMessage(@PathParam("dagJobId") String jobId,String message) { 65 | LOGGER.info(" jobId {} process msg is {} ",jobId,message); 66 | } 67 | 68 | @OnError 69 | public void onError(Session session, Throwable thr) { 70 | try { 71 | session.close(); 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | } 75 | thr.printStackTrace(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/controller/websocket/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.controller.websocket; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 6 | 7 | /** 8 | * @Author: jaytan 9 | * @Description: 创建websocket endpoint 10 | * @Date: 2021/8/5 11 | */ 12 | @Configuration 13 | public class WebSocketConfig { 14 | 15 | @Bean 16 | public ServerEndpointExporter serverEndpointExporter() { 17 | return new ServerEndpointExporter(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/alarm/JobAlarm.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.alarm; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobInfo; 4 | import com.yueshuo.scheduler.admin.core.model.XxlJobLog; 5 | 6 | /** 7 | * @author xuxueli 2020-01-19 8 | */ 9 | public interface JobAlarm { 10 | 11 | /** 12 | * job alarm 13 | * 14 | * @param info 15 | * @param jobLog 16 | * @return 17 | */ 18 | public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/alarm/JobAlarmer.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.alarm; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobInfo; 4 | import com.yueshuo.scheduler.admin.core.model.XxlJobLog; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.BeansException; 8 | import org.springframework.beans.factory.InitializingBean; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.ApplicationContextAware; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | @Component 18 | public class JobAlarmer implements ApplicationContextAware, InitializingBean { 19 | private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class); 20 | 21 | private ApplicationContext applicationContext; 22 | private List jobAlarmList; 23 | 24 | @Override 25 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 26 | this.applicationContext = applicationContext; 27 | } 28 | 29 | @Override 30 | public void afterPropertiesSet() throws Exception { 31 | Map serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class); 32 | if (serviceBeanMap != null && serviceBeanMap.size() > 0) { 33 | jobAlarmList = new ArrayList(serviceBeanMap.values()); 34 | } 35 | } 36 | 37 | /** 38 | * job alarm 39 | * 40 | * @param info 41 | * @param jobLog 42 | * @return 43 | */ 44 | public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) { 45 | 46 | boolean result = false; 47 | if (jobAlarmList!=null && jobAlarmList.size()>0) { 48 | result = true; // success means all-success 49 | for (JobAlarm alarm: jobAlarmList) { 50 | boolean resultItem = false; 51 | try { 52 | resultItem = alarm.doAlarm(info, jobLog); 53 | } catch (Exception e) { 54 | logger.error(e.getMessage(), e); 55 | } 56 | if (!resultItem) { 57 | result = false; 58 | } 59 | } 60 | } 61 | 62 | return result; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/dag/DAGExecutorBlockStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.dag; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 5 | 6 | public enum DAGExecutorBlockStrategyEnum { 7 | 8 | DISCARD_LATER(I18nUtil.getString("jobconf_block_DISCARD_LATER")), 9 | SERIAL_EXECUTION(I18nUtil.getString("jobconf_block_SERIAL_EXECUTION")), 10 | COVER_EARLY(I18nUtil.getString("jobconf_block_CONCURRENT_EXECUTION")), ; 11 | 12 | DAGExecutorBlockStrategyEnum(String title) { 13 | this.title = title; 14 | } 15 | 16 | private String title; 17 | private ExecutorRouter router; 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | public ExecutorRouter getRouter() { 23 | return router; 24 | } 25 | 26 | public static DAGExecutorBlockStrategyEnum match(String name, DAGExecutorBlockStrategyEnum defaultItem){ 27 | if (name != null) { 28 | for (DAGExecutorBlockStrategyEnum item: DAGExecutorBlockStrategyEnum.values()) { 29 | if (item.name().equals(name)) { 30 | return item; 31 | } 32 | } 33 | } 34 | return defaultItem; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/dag/DAGQueueMgr.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.dag; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobInfo; 4 | 5 | import java.util.LinkedList; 6 | import java.util.Map; 7 | import java.util.Queue; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | /** 11 | * DAG 调度排队执行 维护 12 | * 每个调度一个队列,放到map中记录 13 | */ 14 | public class DAGQueueMgr { 15 | private volatile static Map> queueData = new ConcurrentHashMap<>(); 16 | 17 | public static boolean put2Queue(PstDagJobInfo dagJobInfo) { 18 | Queue queues = queueData.get(dagJobInfo.getId()+"") ; 19 | if(queues == null){ 20 | queues = new LinkedList(); 21 | } 22 | boolean flag = queues.offer(dagJobInfo) ; 23 | queueData.put(dagJobInfo.getId()+"",queues) ; 24 | 25 | return flag ; 26 | } 27 | 28 | public static PstDagJobInfo getInQueue(PstDagJobInfo dagJobInfo) { 29 | Queue queues = queueData.get(dagJobInfo.getId()+"") ; 30 | if(queues == null || queues.size() <= 0){ 31 | return null ; 32 | } 33 | return queues.poll() ; 34 | } 35 | 36 | public static int getQueueSize(PstDagJobInfo dagJobInfo) { 37 | Queue queues = queueData.get(dagJobInfo.getId()+"") ; 38 | if(queues == null || queues.size() <= 0){ 39 | return 0 ; 40 | } 41 | return queues.size() ; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/dag/DAGRunRecordCacheUtils.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.dag; 2 | 3 | import com.google.common.cache.Cache; 4 | import com.google.common.cache.CacheBuilder; 5 | 6 | import java.util.Collection; 7 | import java.util.Map; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * DAG 运行记录即时缓存 12 | * @Author: jaytan 13 | * @Description: 14 | * @Date: 2021/8/6 15 | */ 16 | public class DAGRunRecordCacheUtils { 17 | private static Cache loadingCache = CacheBuilder.newBuilder() 18 | /*设置缓存容器的初始容量大小为10*/ 19 | .initialCapacity(10) 20 | /*设置缓存容器的最大容量大小为2000*/ 21 | .maximumSize(20000) 22 | /*设置记录缓存命中率*/ 23 | .recordStats() 24 | /*设置并发级别为8,智并发基本值可以同事先缓存的线程数*/ 25 | .concurrencyLevel(8) 26 | /*设置过期时间为15分钟*/ 27 | .expireAfterAccess(48, TimeUnit.HOURS).build(); 28 | 29 | public static void put(String key, Object value) { 30 | loadingCache.put(key, value); 31 | } 32 | 33 | public static Object get(String key) { 34 | return loadingCache.getIfPresent(key); 35 | } 36 | 37 | public static void remove(String key) { 38 | loadingCache.invalidate(key); 39 | } 40 | 41 | public static void emptyCache() { 42 | loadingCache.invalidateAll(); 43 | } 44 | 45 | public static Map getAll() { 46 | return loadingCache.asMap(); 47 | } 48 | 49 | public static Collection getAllValue() { 50 | return loadingCache.asMap().values(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/exception/XxlJobException.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.exception; 2 | 3 | /** 4 | * @author xuxueli 2019-05-04 23:19:29 5 | */ 6 | public class XxlJobException extends RuntimeException { 7 | 8 | public XxlJobException() { 9 | } 10 | public XxlJobException(String message) { 11 | super(message); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/log/TailLogThread.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.log; 2 | 3 | import javax.websocket.Session; 4 | import java.io.BufferedReader; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | 9 | /** 10 | * @Author: jaytan 11 | * @Description: 读取日志内容,发送websocket 12 | * @Date: 2021/8/5 13 | */ 14 | public class TailLogThread extends Thread { 15 | 16 | private BufferedReader reader; 17 | private Session session; 18 | 19 | public TailLogThread(InputStream in, Session session) { 20 | this.reader = new BufferedReader(new InputStreamReader(in)); 21 | this.session = session; 22 | 23 | } 24 | 25 | @Override 26 | public void run() { 27 | try { 28 | String line; 29 | while ((line = reader.readLine()) != null) { 30 | // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行 31 | session.getBasicRemote().sendText(line + "
"); 32 | } 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/PstDagJobRunRecordInfo.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | public class PstDagJobRunRecordInfo { 6 | private long id ; //ID 编号 7 | private long dagJobId; 8 | private String runRecord; 9 | private long jobId; 10 | private int runMod ; 11 | private int runStatus; 12 | private Date runStartTime; 13 | private Date runEndTime; 14 | private int dagTaskType; 15 | private long startUpJobId; 16 | private Date createTime ; 17 | private long runDataTime ; 18 | 19 | 20 | public long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(long id) { 25 | this.id = id; 26 | } 27 | 28 | public long getDagJobId() { 29 | return dagJobId; 30 | } 31 | 32 | public void setDagJobId(long dagJobId) { 33 | this.dagJobId = dagJobId; 34 | } 35 | 36 | public String getRunRecord() { 37 | return runRecord; 38 | } 39 | 40 | public void setRunRecord(String runRecord) { 41 | this.runRecord = runRecord; 42 | } 43 | 44 | public long getJobId() { 45 | return jobId; 46 | } 47 | 48 | public void setJobId(long jobId) { 49 | this.jobId = jobId; 50 | } 51 | 52 | public int getRunStatus() { 53 | return runStatus; 54 | } 55 | 56 | public void setRunStatus(int runStatus) { 57 | this.runStatus = runStatus; 58 | } 59 | 60 | public Date getRunStartTime() { 61 | return runStartTime; 62 | } 63 | 64 | public void setRunStartTime(Date runStartTime) { 65 | this.runStartTime = runStartTime; 66 | } 67 | 68 | public Date getRunEndTime() { 69 | return runEndTime; 70 | } 71 | 72 | public void setRunEndTime(Date runEndTime) { 73 | this.runEndTime = runEndTime; 74 | } 75 | 76 | public int getDagTaskType() { 77 | return dagTaskType; 78 | } 79 | 80 | public void setDagTaskType(int dagTaskType) { 81 | this.dagTaskType = dagTaskType; 82 | } 83 | 84 | public long getStartUpJobId() { 85 | return startUpJobId; 86 | } 87 | 88 | public void setStartUpJobId(long startUpJobId) { 89 | this.startUpJobId = startUpJobId; 90 | } 91 | 92 | public Date getCreateTime() { 93 | return createTime; 94 | } 95 | 96 | public void setCreateTime(Date createTime) { 97 | this.createTime = createTime; 98 | } 99 | 100 | public int getRunMod() { 101 | return runMod; 102 | } 103 | 104 | public void setRunMod(int runMod) { 105 | this.runMod = runMod; 106 | } 107 | 108 | public long getRunDataTime() { 109 | return runDataTime; 110 | } 111 | 112 | public void setRunDataTime(long runDataTime) { 113 | this.runDataTime = runDataTime; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/XxlJobGroup.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by xuxueli on 16/9/30. 10 | */ 11 | public class XxlJobGroup { 12 | 13 | private int id; 14 | private String appname; 15 | private String title; 16 | private int addressType; // 执行器地址类型:0=自动注册、1=手动录入 17 | private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入) 18 | private Date updateTime; 19 | 20 | // registry list 21 | private List registryList; // 执行器地址列表(系统注册) 22 | public List getRegistryList() { 23 | if (addressList!=null && addressList.trim().length()>0) { 24 | registryList = new ArrayList(Arrays.asList(addressList.split(","))); 25 | } 26 | return registryList; 27 | } 28 | 29 | public int getId() { 30 | return id; 31 | } 32 | 33 | public void setId(int id) { 34 | this.id = id; 35 | } 36 | 37 | public String getAppname() { 38 | return appname; 39 | } 40 | 41 | public void setAppname(String appname) { 42 | this.appname = appname; 43 | } 44 | 45 | public String getTitle() { 46 | return title; 47 | } 48 | 49 | public void setTitle(String title) { 50 | this.title = title; 51 | } 52 | 53 | public int getAddressType() { 54 | return addressType; 55 | } 56 | 57 | public void setAddressType(int addressType) { 58 | this.addressType = addressType; 59 | } 60 | 61 | public String getAddressList() { 62 | return addressList; 63 | } 64 | 65 | public Date getUpdateTime() { 66 | return updateTime; 67 | } 68 | 69 | public void setUpdateTime(Date updateTime) { 70 | this.updateTime = updateTime; 71 | } 72 | 73 | public void setAddressList(String addressList) { 74 | this.addressList = addressList; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/XxlJobLogGlue.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * xxl-job log for glue, used to track job code process 7 | * @author xuxueli 2016-5-19 17:57:46 8 | */ 9 | public class XxlJobLogGlue { 10 | 11 | private int id; 12 | private int jobId; // 任务主键ID 13 | private String glueType; // GLUE类型 #com.yueshuo.scheduler.core.glue.GlueTypeEnum 14 | private String glueSource; 15 | private String glueRemark; 16 | private Date addTime; 17 | private Date updateTime; 18 | 19 | public int getId() { 20 | return id; 21 | } 22 | 23 | public void setId(int id) { 24 | this.id = id; 25 | } 26 | 27 | public int getJobId() { 28 | return jobId; 29 | } 30 | 31 | public void setJobId(int jobId) { 32 | this.jobId = jobId; 33 | } 34 | 35 | public String getGlueType() { 36 | return glueType; 37 | } 38 | 39 | public void setGlueType(String glueType) { 40 | this.glueType = glueType; 41 | } 42 | 43 | public String getGlueSource() { 44 | return glueSource; 45 | } 46 | 47 | public void setGlueSource(String glueSource) { 48 | this.glueSource = glueSource; 49 | } 50 | 51 | public String getGlueRemark() { 52 | return glueRemark; 53 | } 54 | 55 | public void setGlueRemark(String glueRemark) { 56 | this.glueRemark = glueRemark; 57 | } 58 | 59 | public Date getAddTime() { 60 | return addTime; 61 | } 62 | 63 | public void setAddTime(Date addTime) { 64 | this.addTime = addTime; 65 | } 66 | 67 | public Date getUpdateTime() { 68 | return updateTime; 69 | } 70 | 71 | public void setUpdateTime(Date updateTime) { 72 | this.updateTime = updateTime; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/XxlJobLogReport.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | public class XxlJobLogReport { 6 | 7 | private int id; 8 | 9 | private Date triggerDay; 10 | 11 | private int runningCount; 12 | private int sucCount; 13 | private int failCount; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public void setId(int id) { 20 | this.id = id; 21 | } 22 | 23 | public Date getTriggerDay() { 24 | return triggerDay; 25 | } 26 | 27 | public void setTriggerDay(Date triggerDay) { 28 | this.triggerDay = triggerDay; 29 | } 30 | 31 | public int getRunningCount() { 32 | return runningCount; 33 | } 34 | 35 | public void setRunningCount(int runningCount) { 36 | this.runningCount = runningCount; 37 | } 38 | 39 | public int getSucCount() { 40 | return sucCount; 41 | } 42 | 43 | public void setSucCount(int sucCount) { 44 | this.sucCount = sucCount; 45 | } 46 | 47 | public int getFailCount() { 48 | return failCount; 49 | } 50 | 51 | public void setFailCount(int failCount) { 52 | this.failCount = failCount; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/XxlJobRegistry.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Created by xuxueli on 16/9/30. 7 | */ 8 | public class XxlJobRegistry { 9 | 10 | private int id; 11 | private String registryGroup; 12 | private String registryKey; 13 | private String registryValue; 14 | private Date updateTime; 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public String getRegistryGroup() { 25 | return registryGroup; 26 | } 27 | 28 | public void setRegistryGroup(String registryGroup) { 29 | this.registryGroup = registryGroup; 30 | } 31 | 32 | public String getRegistryKey() { 33 | return registryKey; 34 | } 35 | 36 | public void setRegistryKey(String registryKey) { 37 | this.registryKey = registryKey; 38 | } 39 | 40 | public String getRegistryValue() { 41 | return registryValue; 42 | } 43 | 44 | public void setRegistryValue(String registryValue) { 45 | this.registryValue = registryValue; 46 | } 47 | 48 | public Date getUpdateTime() { 49 | return updateTime; 50 | } 51 | 52 | public void setUpdateTime(Date updateTime) { 53 | this.updateTime = updateTime; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/model/XxlJobUser.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.model; 2 | 3 | import org.springframework.util.StringUtils; 4 | 5 | /** 6 | * @author xuxueli 2019-05-04 16:43:12 7 | */ 8 | public class XxlJobUser { 9 | 10 | private int id; 11 | private String username; // 账号 12 | private String password; // 密码 13 | private int role; // 角色:0-普通用户、1-管理员 14 | private String permission; // 权限:执行器ID列表,多个逗号分割 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public void setUsername(String username) { 29 | this.username = username; 30 | } 31 | 32 | public String getPassword() { 33 | return password; 34 | } 35 | 36 | public void setPassword(String password) { 37 | this.password = password; 38 | } 39 | 40 | public int getRole() { 41 | return role; 42 | } 43 | 44 | public void setRole(int role) { 45 | this.role = role; 46 | } 47 | 48 | public String getPermission() { 49 | return permission; 50 | } 51 | 52 | public void setPermission(String permission) { 53 | this.permission = permission; 54 | } 55 | 56 | // plugin 57 | public boolean validPermission(int jobGroup){ 58 | if (this.role == 1) { 59 | return true; 60 | } else { 61 | if (StringUtils.hasText(this.permission)) { 62 | for (String permissionItem : this.permission.split(",")) { 63 | if (String.valueOf(jobGroup).equals(permissionItem)) { 64 | return true; 65 | } 66 | } 67 | } 68 | return false; 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/old/RemoteHttpJobBean.java: -------------------------------------------------------------------------------- 1 | //package com.yueshuo.scheduler.admin.core.jobbean; 2 | // 3 | //import com.yueshuo.scheduler.admin.core.thread.JobTriggerPoolHelper; 4 | //import com.yueshuo.scheduler.admin.core.trigger.TriggerTypeEnum; 5 | //import org.quartz.JobExecutionContext; 6 | //import org.quartz.JobExecutionException; 7 | //import org.quartz.JobKey; 8 | //import org.slf4j.Logger; 9 | //import org.slf4j.LoggerFactory; 10 | //import org.springframework.scheduling.quartz.QuartzJobBean; 11 | // 12 | ///** 13 | // * http job bean 14 | // * “@DisallowConcurrentExecution” disable concurrent, thread size can not be only one, better given more 15 | // * @author xuxueli 2015-12-17 18:20:34 16 | // */ 17 | ////@DisallowConcurrentExecution 18 | //public class RemoteHttpJobBean extends QuartzJobBean { 19 | // private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class); 20 | // 21 | // @Override 22 | // protected void executeInternal(JobExecutionContext context) 23 | // throws JobExecutionException { 24 | // 25 | // // load jobId 26 | // JobKey jobKey = context.getTrigger().getJobKey(); 27 | // Integer jobId = Integer.valueOf(jobKey.getName()); 28 | // 29 | // 30 | // } 31 | // 32 | //} -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/old/XxlJobThreadPool.java: -------------------------------------------------------------------------------- 1 | //package com.yueshuo.scheduler.admin.core.quartz; 2 | // 3 | //import org.quartz.SchedulerConfigException; 4 | //import org.quartz.spi.ThreadPool; 5 | // 6 | ///** 7 | // * single thread pool, for async trigger 8 | // * 9 | // * @author xuxueli 2019-03-06 10 | // */ 11 | //public class XxlJobThreadPool implements ThreadPool { 12 | // 13 | // @Override 14 | // public boolean runInThread(Runnable runnable) { 15 | // 16 | // // async run 17 | // runnable.run(); 18 | // return true; 19 | // 20 | // //return false; 21 | // } 22 | // 23 | // @Override 24 | // public int blockForAvailableThreads() { 25 | // return 1; 26 | // } 27 | // 28 | // @Override 29 | // public void initialize() throws SchedulerConfigException { 30 | // 31 | // } 32 | // 33 | // @Override 34 | // public void shutdown(boolean waitForJobsToComplete) { 35 | // 36 | // } 37 | // 38 | // @Override 39 | // public int getPoolSize() { 40 | // return 1; 41 | // } 42 | // 43 | // @Override 44 | // public void setInstanceId(String schedInstId) { 45 | // 46 | // } 47 | // 48 | // @Override 49 | // public void setInstanceName(String schedName) { 50 | // 51 | // } 52 | // 53 | // // support 54 | // public void setThreadCount(int count) { 55 | // // 56 | // } 57 | // 58 | //} 59 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/ExecutorRouteStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.strategy.*; 4 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 5 | 6 | /** 7 | * Created by xuxueli on 17/3/10. 8 | */ 9 | public enum ExecutorRouteStrategyEnum { 10 | 11 | FIRST(I18nUtil.getString("jobconf_route_first"), new ExecutorRouteFirst()), 12 | LAST(I18nUtil.getString("jobconf_route_last"), new ExecutorRouteLast()), 13 | ROUND(I18nUtil.getString("jobconf_route_round"), new ExecutorRouteRound()), 14 | RANDOM(I18nUtil.getString("jobconf_route_random"), new ExecutorRouteRandom()), 15 | CONSISTENT_HASH(I18nUtil.getString("jobconf_route_consistenthash"), new ExecutorRouteConsistentHash()), 16 | LEAST_FREQUENTLY_USED(I18nUtil.getString("jobconf_route_lfu"), new ExecutorRouteLFU()), 17 | LEAST_RECENTLY_USED(I18nUtil.getString("jobconf_route_lru"), new ExecutorRouteLRU()), 18 | FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover()), 19 | BUSYOVER(I18nUtil.getString("jobconf_route_busyover"), new ExecutorRouteBusyover()), 20 | SHARDING_BROADCAST(I18nUtil.getString("jobconf_route_shard"), null); 21 | 22 | ExecutorRouteStrategyEnum(String title, ExecutorRouter router) { 23 | this.title = title; 24 | this.router = router; 25 | } 26 | 27 | private String title; 28 | private ExecutorRouter router; 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | public ExecutorRouter getRouter() { 34 | return router; 35 | } 36 | 37 | public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){ 38 | if (name != null) { 39 | for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) { 40 | if (item.name().equals(name)) { 41 | return item; 42 | } 43 | } 44 | } 45 | return defaultItem; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/ExecutorRouter.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route; 2 | 3 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 4 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by xuxueli on 17/3/10. 12 | */ 13 | public abstract class ExecutorRouter { 14 | protected static Logger logger = LoggerFactory.getLogger(ExecutorRouter.class); 15 | 16 | /** 17 | * route address 18 | * 19 | * @param addressList 20 | * @return ReturnT.content=address 21 | */ 22 | public abstract ReturnT route(TriggerParam triggerParam, List addressList); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteBusyover.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.scheduler.XxlJobScheduler; 4 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 5 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 6 | import com.yueshuo.scheduler.core.biz.ExecutorBiz; 7 | import com.yueshuo.scheduler.core.biz.model.IdleBeatParam; 8 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 9 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by xuxueli on 17/3/10. 15 | */ 16 | public class ExecutorRouteBusyover extends ExecutorRouter { 17 | 18 | @Override 19 | public ReturnT route(TriggerParam triggerParam, List addressList) { 20 | StringBuffer idleBeatResultSB = new StringBuffer(); 21 | for (String address : addressList) { 22 | // beat 23 | ReturnT idleBeatResult = null; 24 | try { 25 | ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); 26 | idleBeatResult = executorBiz.idleBeat(new IdleBeatParam(triggerParam.getJobId())); 27 | } catch (Exception e) { 28 | logger.error(e.getMessage(), e); 29 | idleBeatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); 30 | } 31 | idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"

":"") 32 | .append(I18nUtil.getString("jobconf_idleBeat") + ":") 33 | .append("
address:").append(address) 34 | .append("
code:").append(idleBeatResult.getCode()) 35 | .append("
msg:").append(idleBeatResult.getMsg()); 36 | 37 | // beat success 38 | if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) { 39 | idleBeatResult.setMsg(idleBeatResultSB.toString()); 40 | idleBeatResult.setContent(address); 41 | return idleBeatResult; 42 | } 43 | } 44 | 45 | return new ReturnT(ReturnT.FAIL_CODE, idleBeatResultSB.toString()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteFailover.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.scheduler.XxlJobScheduler; 4 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 5 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 6 | import com.yueshuo.scheduler.core.biz.ExecutorBiz; 7 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 8 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by xuxueli on 17/3/10. 14 | */ 15 | public class ExecutorRouteFailover extends ExecutorRouter { 16 | 17 | @Override 18 | public ReturnT route(TriggerParam triggerParam, List addressList) { 19 | 20 | StringBuffer beatResultSB = new StringBuffer(); 21 | for (String address : addressList) { 22 | // beat 23 | ReturnT beatResult = null; 24 | try { 25 | ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address); 26 | beatResult = executorBiz.beat(); 27 | } catch (Exception e) { 28 | logger.error(e.getMessage(), e); 29 | beatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e ); 30 | } 31 | beatResultSB.append( (beatResultSB.length()>0)?"

":"") 32 | .append(I18nUtil.getString("jobconf_beat") + ":") 33 | .append("
address:").append(address) 34 | .append("
code:").append(beatResult.getCode()) 35 | .append("
msg:").append(beatResult.getMsg()); 36 | 37 | // beat success 38 | if (beatResult.getCode() == ReturnT.SUCCESS_CODE) { 39 | 40 | beatResult.setMsg(beatResultSB.toString()); 41 | beatResult.setContent(address); 42 | return beatResult; 43 | } 44 | } 45 | return new ReturnT(ReturnT.FAIL_CODE, beatResultSB.toString()); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteFirst.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by xuxueli on 17/3/10. 11 | */ 12 | public class ExecutorRouteFirst extends ExecutorRouter { 13 | 14 | @Override 15 | public ReturnT route(TriggerParam triggerParam, List addressList){ 16 | return new ReturnT(addressList.get(0)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteLRU.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 6 | 7 | import java.util.ArrayList; 8 | import java.util.LinkedHashMap; 9 | import java.util.List; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.util.concurrent.ConcurrentMap; 12 | 13 | /** 14 | * 单个JOB对应的每个执行器,最久为使用的优先被选举 15 | * a、LFU(Least Frequently Used):最不经常使用,频率/次数 16 | * b(*)、LRU(Least Recently Used):最近最久未使用,时间 17 | * 18 | * Created by xuxueli on 17/3/10. 19 | */ 20 | public class ExecutorRouteLRU extends ExecutorRouter { 21 | 22 | private static ConcurrentMap> jobLRUMap = new ConcurrentHashMap>(); 23 | private static long CACHE_VALID_TIME = 0; 24 | 25 | public String route(int jobId, List addressList) { 26 | 27 | // cache clear 28 | if (System.currentTimeMillis() > CACHE_VALID_TIME) { 29 | jobLRUMap.clear(); 30 | CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; 31 | } 32 | 33 | // init lru 34 | LinkedHashMap lruItem = jobLRUMap.get(jobId); 35 | if (lruItem == null) { 36 | /** 37 | * LinkedHashMap 38 | * a、accessOrder:true=访问顺序排序(get/put时排序);false=插入顺序排期; 39 | * b、removeEldestEntry:新增元素时将会调用,返回true时会删除最老元素;可封装LinkedHashMap并重写该方法,比如定义最大容量,超出是返回true即可实现固定长度的LRU算法; 40 | */ 41 | lruItem = new LinkedHashMap(16, 0.75f, true); 42 | jobLRUMap.putIfAbsent(jobId, lruItem); 43 | } 44 | 45 | // put new 46 | for (String address: addressList) { 47 | if (!lruItem.containsKey(address)) { 48 | lruItem.put(address, address); 49 | } 50 | } 51 | // remove old 52 | List delKeys = new ArrayList<>(); 53 | for (String existKey: lruItem.keySet()) { 54 | if (!addressList.contains(existKey)) { 55 | delKeys.add(existKey); 56 | } 57 | } 58 | if (delKeys.size() > 0) { 59 | for (String delKey: delKeys) { 60 | lruItem.remove(delKey); 61 | } 62 | } 63 | 64 | // load 65 | String eldestKey = lruItem.entrySet().iterator().next().getKey(); 66 | String eldestValue = lruItem.get(eldestKey); 67 | return eldestValue; 68 | } 69 | 70 | @Override 71 | public ReturnT route(TriggerParam triggerParam, List addressList) { 72 | String address = route(triggerParam.getJobId(), addressList); 73 | return new ReturnT(address); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteLast.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by xuxueli on 17/3/10. 11 | */ 12 | public class ExecutorRouteLast extends ExecutorRouter { 13 | 14 | @Override 15 | public ReturnT route(TriggerParam triggerParam, List addressList) { 16 | return new ReturnT(addressList.get(addressList.size()-1)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteRandom.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | /** 11 | * Created by xuxueli on 17/3/10. 12 | */ 13 | public class ExecutorRouteRandom extends ExecutorRouter { 14 | 15 | private static Random localRandom = new Random(); 16 | 17 | @Override 18 | public ReturnT route(TriggerParam triggerParam, List addressList) { 19 | String address = addressList.get(localRandom.nextInt(addressList.size())); 20 | return new ReturnT(address); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/route/strategy/ExecutorRouteRound.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.route.strategy; 2 | 3 | import com.yueshuo.scheduler.admin.core.route.ExecutorRouter; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | import com.yueshuo.scheduler.core.biz.model.TriggerParam; 6 | 7 | import java.util.List; 8 | import java.util.Random; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.ConcurrentMap; 11 | import java.util.concurrent.atomic.AtomicInteger; 12 | 13 | /** 14 | * Created by xuxueli on 17/3/10. 15 | */ 16 | public class ExecutorRouteRound extends ExecutorRouter { 17 | 18 | private static ConcurrentMap routeCountEachJob = new ConcurrentHashMap<>(); 19 | private static long CACHE_VALID_TIME = 0; 20 | 21 | private static int count(int jobId) { 22 | // cache clear 23 | if (System.currentTimeMillis() > CACHE_VALID_TIME) { 24 | routeCountEachJob.clear(); 25 | CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; 26 | } 27 | 28 | AtomicInteger count = routeCountEachJob.get(jobId); 29 | if (count == null || count.get() > 1000000) { 30 | // 初始化时主动Random一次,缓解首次压力 31 | count = new AtomicInteger(new Random().nextInt(100)); 32 | } else { 33 | // count++ 34 | count.addAndGet(1); 35 | } 36 | routeCountEachJob.put(jobId, count); 37 | return count.get(); 38 | } 39 | 40 | @Override 41 | public ReturnT route(TriggerParam triggerParam, List addressList) { 42 | String address = addressList.get(count(triggerParam.getJobId())%addressList.size()); 43 | return new ReturnT(address); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/scheduler/MisfireStrategyEnum.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.scheduler; 2 | 3 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * @author xuxueli 2020-10-29 21:11:23 7 | */ 8 | public enum MisfireStrategyEnum { 9 | 10 | /** 11 | * do nothing 12 | */ 13 | DO_NOTHING(I18nUtil.getString("misfire_strategy_do_nothing")), 14 | 15 | /** 16 | * fire once now 17 | */ 18 | FIRE_ONCE_NOW(I18nUtil.getString("misfire_strategy_fire_once_now")); 19 | 20 | private String title; 21 | 22 | MisfireStrategyEnum(String title) { 23 | this.title = title; 24 | } 25 | 26 | public String getTitle() { 27 | return title; 28 | } 29 | 30 | public static MisfireStrategyEnum match(String name, MisfireStrategyEnum defaultItem){ 31 | for (MisfireStrategyEnum item: MisfireStrategyEnum.values()) { 32 | if (item.name().equals(name)) { 33 | return item; 34 | } 35 | } 36 | return defaultItem; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/scheduler/ScheduleTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.scheduler; 2 | 3 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * @author xuxueli 2020-10-29 21:11:23 7 | */ 8 | public enum ScheduleTypeEnum { 9 | 10 | NONE(I18nUtil.getString("schedule_type_none")), 11 | 12 | /** 13 | * schedule by cron 14 | */ 15 | CRON(I18nUtil.getString("schedule_type_cron")), 16 | 17 | /** 18 | * schedule by fixed rate (in seconds) 19 | */ 20 | FIX_RATE(I18nUtil.getString("schedule_type_fix_rate")), 21 | 22 | /** 23 | * schedule by fix delay (in seconds), after the last time 24 | */ 25 | /*FIX_DELAY(I18nUtil.getString("schedule_type_fix_delay"))*/; 26 | 27 | private String title; 28 | 29 | ScheduleTypeEnum(String title) { 30 | this.title = title; 31 | } 32 | 33 | public String getTitle() { 34 | return title; 35 | } 36 | 37 | public static ScheduleTypeEnum match(String name, ScheduleTypeEnum defaultItem){ 38 | for (ScheduleTypeEnum item: ScheduleTypeEnum.values()) { 39 | if (item.name().equals(name)) { 40 | return item; 41 | } 42 | } 43 | return defaultItem; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/trigger/TriggerTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.trigger; 2 | 3 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 4 | 5 | /** 6 | * trigger type enum 7 | * 8 | * @author xuxueli 2018-09-16 04:56:41 9 | */ 10 | public enum TriggerTypeEnum { 11 | 12 | MANUAL(I18nUtil.getString("jobconf_trigger_type_manual")), 13 | CRON(I18nUtil.getString("jobconf_trigger_type_cron")), 14 | RETRY(I18nUtil.getString("jobconf_trigger_type_retry")), 15 | PARENT(I18nUtil.getString("jobconf_trigger_type_parent")), 16 | API(I18nUtil.getString("jobconf_trigger_type_api")), 17 | MISFIRE(I18nUtil.getString("jobconf_trigger_type_misfire")); 18 | 19 | private TriggerTypeEnum(String title){ 20 | this.title = title; 21 | } 22 | private String title; 23 | public String getTitle() { 24 | return title; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/util/BeanCopyUtils.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.util; 2 | 3 | import org.springframework.beans.BeanUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Supplier; 8 | 9 | public class BeanCopyUtils extends BeanUtils { 10 | /** 11 | * 集合数据的拷贝 12 | * @param sources: 数据源类 13 | * @param target: 目标类::new(eg: UserVO::new) 14 | * @return 15 | */ 16 | public static List copyListProperties(List sources, Supplier target) { 17 | return copyListProperties(sources, target, null); 18 | } 19 | 20 | 21 | /** 22 | * 带回调函数的集合数据的拷贝(可自定义字段拷贝规则) 23 | * @param sources: 数据源类 24 | * @param target: 目标类::new(eg: UserVO::new) 25 | * @param callBack: 回调函数 26 | * @return 27 | */ 28 | public static List copyListProperties(List sources, Supplier target, BeanCopyUtilCallBack callBack) { 29 | List list = new ArrayList<>(sources.size()); 30 | for (S source : sources) { 31 | T t = target.get(); 32 | copyProperties(source, t); 33 | list.add(t); 34 | if (callBack != null) { 35 | // 回调 36 | callBack.callBack(source, t); 37 | } 38 | } 39 | return list; 40 | } 41 | 42 | 43 | @FunctionalInterface 44 | public interface BeanCopyUtilCallBack { 45 | /** 46 | * 定义默认回调方法 47 | * @param t 48 | * @param s 49 | */ 50 | void callBack(S t, T s); 51 | } 52 | 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/util/CookieUtil.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.util; 2 | 3 | import javax.servlet.http.Cookie; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | 7 | /** 8 | * Cookie.Util 9 | * 10 | * @author xuxueli 2015-12-12 18:01:06 11 | */ 12 | public class CookieUtil { 13 | 14 | // 默认缓存时间,单位/秒, 2H 15 | private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE; 16 | // 保存路径,根路径 17 | private static final String COOKIE_PATH = "/"; 18 | 19 | /** 20 | * 保存 21 | * 22 | * @param response 23 | * @param key 24 | * @param value 25 | * @param ifRemember 26 | */ 27 | public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) { 28 | int age = ifRemember?COOKIE_MAX_AGE:-1; 29 | set(response, key, value, null, COOKIE_PATH, age, true); 30 | } 31 | 32 | /** 33 | * 保存 34 | * 35 | * @param response 36 | * @param key 37 | * @param value 38 | * @param maxAge 39 | */ 40 | private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) { 41 | Cookie cookie = new Cookie(key, value); 42 | if (domain != null) { 43 | cookie.setDomain(domain); 44 | } 45 | cookie.setPath(path); 46 | cookie.setMaxAge(maxAge); 47 | cookie.setHttpOnly(isHttpOnly); 48 | response.addCookie(cookie); 49 | } 50 | 51 | /** 52 | * 查询value 53 | * 54 | * @param request 55 | * @param key 56 | * @return 57 | */ 58 | public static String getValue(HttpServletRequest request, String key) { 59 | Cookie cookie = get(request, key); 60 | if (cookie != null) { 61 | return cookie.getValue(); 62 | } 63 | return null; 64 | } 65 | 66 | /** 67 | * 查询Cookie 68 | * 69 | * @param request 70 | * @param key 71 | */ 72 | private static Cookie get(HttpServletRequest request, String key) { 73 | Cookie[] arr_cookie = request.getCookies(); 74 | if (arr_cookie != null && arr_cookie.length > 0) { 75 | for (Cookie cookie : arr_cookie) { 76 | if (cookie.getName().equals(key)) { 77 | return cookie; 78 | } 79 | } 80 | } 81 | return null; 82 | } 83 | 84 | /** 85 | * 删除Cookie 86 | * 87 | * @param request 88 | * @param response 89 | * @param key 90 | */ 91 | public static void remove(HttpServletRequest request, HttpServletResponse response, String key) { 92 | Cookie cookie = get(request, key); 93 | if (cookie != null) { 94 | set(response, key, "", null, COOKIE_PATH, 0, true); 95 | } 96 | } 97 | 98 | } -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/util/FtlUtil.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.util; 2 | 3 | import freemarker.ext.beans.BeansWrapper; 4 | import freemarker.ext.beans.BeansWrapperBuilder; 5 | import freemarker.template.Configuration; 6 | import freemarker.template.TemplateHashModel; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | /** 11 | * ftl util 12 | * 13 | * @author xuxueli 2018-01-17 20:37:48 14 | */ 15 | public class FtlUtil { 16 | private static Logger logger = LoggerFactory.getLogger(FtlUtil.class); 17 | 18 | private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); //BeansWrapper.getDefaultInstance(); 19 | 20 | public static TemplateHashModel generateStaticModel(String packageName) { 21 | try { 22 | TemplateHashModel staticModels = wrapper.getStaticModels(); 23 | TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName); 24 | return fileStatics; 25 | } catch (Exception e) { 26 | logger.error(e.getMessage(), e); 27 | } 28 | return null; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/util/I18nUtil.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.util; 2 | 3 | import com.yueshuo.scheduler.admin.core.conf.XxlJobAdminConfig; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.core.io.ClassPathResource; 7 | import org.springframework.core.io.Resource; 8 | import org.springframework.core.io.support.EncodedResource; 9 | import org.springframework.core.io.support.PropertiesLoaderUtils; 10 | 11 | import java.io.IOException; 12 | import java.text.MessageFormat; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.Properties; 16 | 17 | /** 18 | * i18n util 19 | * 20 | * @author xuxueli 2018-01-17 20:39:06 21 | */ 22 | public class I18nUtil { 23 | private static Logger logger = LoggerFactory.getLogger(I18nUtil.class); 24 | 25 | private static Properties prop = null; 26 | public static Properties loadI18nProp(){ 27 | if (prop != null) { 28 | return prop; 29 | } 30 | try { 31 | // build i18n prop 32 | String i18n = XxlJobAdminConfig.getAdminConfig().getI18n(); 33 | String i18nFile = MessageFormat.format("i18n/message_{0}.properties", i18n); 34 | 35 | // load prop 36 | Resource resource = new ClassPathResource(i18nFile); 37 | EncodedResource encodedResource = new EncodedResource(resource,"UTF-8"); 38 | prop = PropertiesLoaderUtils.loadProperties(encodedResource); 39 | } catch (IOException e) { 40 | logger.error(e.getMessage(), e); 41 | } 42 | return prop; 43 | } 44 | 45 | /** 46 | * get val of i18n key 47 | * 48 | * @param key 49 | * @return 50 | */ 51 | public static String getString(String key) { 52 | return loadI18nProp().getProperty(key); 53 | } 54 | 55 | /** 56 | * get mult val of i18n mult key, as json 57 | * 58 | * @param keys 59 | * @return 60 | */ 61 | public static String getMultString(String... keys) { 62 | Map map = new HashMap(); 63 | 64 | Properties prop = loadI18nProp(); 65 | if (keys!=null && keys.length>0) { 66 | for (String key: keys) { 67 | map.put(key, prop.getProperty(key)); 68 | } 69 | } else { 70 | for (String key: prop.stringPropertyNames()) { 71 | map.put(key, prop.getProperty(key)); 72 | } 73 | } 74 | 75 | String json = JacksonUtil.writeValueAsString(map); 76 | return json; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/core/util/JacksonUtil.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.core.util; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerationException; 4 | import com.fasterxml.jackson.core.JsonParseException; 5 | import com.fasterxml.jackson.databind.JavaType; 6 | import com.fasterxml.jackson.databind.JsonMappingException; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * Jackson util 15 | * 16 | * 1、obj need private and set/get; 17 | * 2、do not support inner class; 18 | * 19 | * @author xuxueli 2015-9-25 18:02:56 20 | */ 21 | public class JacksonUtil { 22 | private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class); 23 | 24 | private final static ObjectMapper objectMapper = new ObjectMapper(); 25 | public static ObjectMapper getInstance() { 26 | return objectMapper; 27 | } 28 | 29 | /** 30 | * bean、array、List、Map --> json 31 | * 32 | * @param obj 33 | * @return json string 34 | * @throws Exception 35 | */ 36 | public static String writeValueAsString(Object obj) { 37 | try { 38 | return getInstance().writeValueAsString(obj); 39 | } catch (JsonGenerationException e) { 40 | logger.error(e.getMessage(), e); 41 | } catch (JsonMappingException e) { 42 | logger.error(e.getMessage(), e); 43 | } catch (IOException e) { 44 | logger.error(e.getMessage(), e); 45 | } 46 | return null; 47 | } 48 | 49 | /** 50 | * string --> bean、Map、List(array) 51 | * 52 | * @param jsonStr 53 | * @param clazz 54 | * @return obj 55 | * @throws Exception 56 | */ 57 | public static T readValue(String jsonStr, Class clazz) { 58 | try { 59 | return getInstance().readValue(jsonStr, clazz); 60 | } catch (JsonParseException e) { 61 | logger.error(e.getMessage(), e); 62 | } catch (JsonMappingException e) { 63 | logger.error(e.getMessage(), e); 64 | } catch (IOException e) { 65 | logger.error(e.getMessage(), e); 66 | } 67 | return null; 68 | } 69 | 70 | /** 71 | * string --> List... 72 | * 73 | * @param jsonStr 74 | * @param parametrized 75 | * @param parameterClasses 76 | * @param 77 | * @return 78 | */ 79 | public static T readValue(String jsonStr, Class parametrized, Class... parameterClasses) { 80 | try { 81 | JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses); 82 | return getInstance().readValue(jsonStr, javaType); 83 | } catch (JsonParseException e) { 84 | logger.error(e.getMessage(), e); 85 | } catch (JsonMappingException e) { 86 | logger.error(e.getMessage(), e); 87 | } catch (IOException e) { 88 | logger.error(e.getMessage(), e); 89 | } 90 | return null; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/PstDagJobInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobInfo; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | @Mapper 10 | public interface PstDagJobInfoDao { 11 | public List pageList(@Param("offset") int offset, 12 | @Param("pagesize") int pagesize, 13 | @Param("jobName") String jobName, 14 | @Param("jobDesc") String jobDesc, 15 | @Param("status") int status ); 16 | public int pageListCount(@Param("offset") int offset, 17 | @Param("pagesize") int pagesize, 18 | @Param("jobName") String jobName, 19 | @Param("jobDesc") String jobDesc, 20 | @Param("status") int status ); 21 | 22 | public int save(PstDagJobInfo info); 23 | 24 | public PstDagJobInfo loadById(@Param("id") long id); 25 | 26 | public int update(PstDagJobInfo xxlJobInfo); 27 | 28 | public int updateDagInfo(PstDagJobInfo xxlJobInfo); 29 | 30 | public int updateRunStatusInfo(PstDagJobInfo xxlJobInfo); 31 | 32 | public int delete(@Param("id") long id); 33 | 34 | public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize ); 35 | 36 | public int scheduleUpdate(PstDagJobInfo xxlJobInfo); 37 | } 38 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/PstDagJobRunRecordDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobRunRecordInfo; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | @Mapper 10 | public interface PstDagJobRunRecordDao { 11 | public List pageList(@Param("offset") int offset, 12 | @Param("pagesize") int pagesize, 13 | @Param("jobName") String jobName, 14 | @Param("jobDesc") String jobDesc, 15 | @Param("status") int status ); 16 | public int pageListCount(@Param("offset") int offset, 17 | @Param("pagesize") int pagesize, 18 | @Param("jobName") String jobName, 19 | @Param("jobDesc") String jobDesc, 20 | @Param("status") int status ); 21 | 22 | public int save(PstDagJobRunRecordInfo info); 23 | 24 | public List loadByRunRecord(@Param("runRecord") String runRecord); 25 | 26 | public List loadByDataTimeAndDagJobId(@Param("runDataTime") long dataTime,@Param("dagJobId") long dagJobId); 27 | 28 | public PstDagJobRunRecordInfo loadById(@Param("id") long id); 29 | 30 | public PstDagJobRunRecordInfo loadByRunRecordAndJobId(@Param("runRecord") String runRecord,@Param("jobId") long jobId); 31 | 32 | public PstDagJobRunRecordInfo loadByRunRecordAndDagTaskType (@Param("runRecord") String runRecord,@Param("dagTaskType") int dagTaskType); 33 | 34 | public List loadRunDataTimeByDagJobId(@Param("dagJobId") long dagJobId,@Param("size") int size); 35 | 36 | public int update(PstDagJobRunRecordInfo xxlJobInfo); 37 | 38 | 39 | public int delete(@Param("id") long id); 40 | } 41 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobGroupDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobGroup; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by xuxueli on 16/9/30. 11 | */ 12 | @Mapper 13 | public interface XxlJobGroupDao { 14 | 15 | public List findAll(); 16 | 17 | public List findByAddressType(@Param("addressType") int addressType); 18 | 19 | public int save(XxlJobGroup xxlJobGroup); 20 | 21 | public int update(XxlJobGroup xxlJobGroup); 22 | 23 | public int remove(@Param("id") int id); 24 | 25 | public XxlJobGroup load(@Param("id") int id); 26 | 27 | public List pageList(@Param("offset") int offset, 28 | @Param("pagesize") int pagesize, 29 | @Param("appname") String appname, 30 | @Param("title") String title); 31 | 32 | public int pageListCount(@Param("offset") int offset, 33 | @Param("pagesize") int pagesize, 34 | @Param("appname") String appname, 35 | @Param("title") String title); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobInfo; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * job info 12 | * @author xuxueli 2016-1-12 18:03:45 13 | */ 14 | @Mapper 15 | public interface XxlJobInfoDao { 16 | 17 | public List pageList(@Param("offset") int offset, 18 | @Param("pagesize") int pagesize, 19 | @Param("jobGroup") int jobGroup, 20 | @Param("triggerStatus") int triggerStatus, 21 | @Param("jobDesc") String jobDesc, 22 | @Param("executorHandler") String executorHandler, 23 | @Param("author") String author); 24 | public int pageListCount(@Param("offset") int offset, 25 | @Param("pagesize") int pagesize, 26 | @Param("jobGroup") int jobGroup, 27 | @Param("triggerStatus") int triggerStatus, 28 | @Param("jobDesc") String jobDesc, 29 | @Param("executorHandler") String executorHandler, 30 | @Param("author") String author); 31 | 32 | public int save(XxlJobInfo info); 33 | 34 | public XxlJobInfo loadById(@Param("id") long id); 35 | 36 | public int update(XxlJobInfo xxlJobInfo); 37 | 38 | public int delete(@Param("id") long id); 39 | 40 | public List getJobsByGroup(@Param("jobGroup") int jobGroup); 41 | 42 | public int findAllCount(); 43 | 44 | public List scheduleJobQuery(@Param("maxNextTime") long maxNextTime, @Param("pagesize") int pagesize ); 45 | 46 | public int scheduleUpdate(XxlJobInfo xxlJobInfo); 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobLogDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobLog; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * job log 13 | * @author xuxueli 2016-1-12 18:03:06 14 | */ 15 | @Mapper 16 | public interface XxlJobLogDao { 17 | 18 | // exist jobId not use jobGroup, not exist use jobGroup 19 | public List pageList(@Param("offset") int offset, 20 | @Param("pagesize") int pagesize, 21 | @Param("jobGroup") int jobGroup, 22 | @Param("jobId") int jobId, 23 | @Param("triggerTimeStart") Date triggerTimeStart, 24 | @Param("triggerTimeEnd") Date triggerTimeEnd, 25 | @Param("logStatus") int logStatus); 26 | public int pageListCount(@Param("offset") int offset, 27 | @Param("pagesize") int pagesize, 28 | @Param("jobGroup") int jobGroup, 29 | @Param("jobId") int jobId, 30 | @Param("triggerTimeStart") Date triggerTimeStart, 31 | @Param("triggerTimeEnd") Date triggerTimeEnd, 32 | @Param("logStatus") int logStatus); 33 | 34 | public XxlJobLog load(@Param("id") long id); 35 | 36 | public XxlJobLog loadByJobIdAndDagRunRecord(XxlJobLog xxlJobLog) ; 37 | 38 | public List loadByJobIdLastTimeLog(XxlJobLog xxlJobLog) ; 39 | 40 | public long save(XxlJobLog xxlJobLog); 41 | 42 | public int updateTriggerInfo(XxlJobLog xxlJobLog); 43 | 44 | public int updateHandleInfo(XxlJobLog xxlJobLog); 45 | 46 | public int delete(@Param("jobId") int jobId); 47 | 48 | public Map findLogReport(@Param("from") Date from, 49 | @Param("to") Date to); 50 | 51 | public List findClearLogIds(@Param("jobGroup") int jobGroup, 52 | @Param("jobId") int jobId, 53 | @Param("clearBeforeTime") Date clearBeforeTime, 54 | @Param("clearBeforeNum") int clearBeforeNum, 55 | @Param("pagesize") int pagesize); 56 | public int clearLog(@Param("logIds") List logIds); 57 | 58 | public List findFailJobLogIds(@Param("pagesize") int pagesize); 59 | 60 | public int updateAlarmStatus(@Param("logId") long logId, 61 | @Param("oldAlarmStatus") int oldAlarmStatus, 62 | @Param("newAlarmStatus") int newAlarmStatus); 63 | 64 | public List findLostJobIds(@Param("losedTime") Date losedTime); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobLogGlueDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobLogGlue; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * job log for glue 11 | * @author xuxueli 2016-5-19 18:04:56 12 | */ 13 | @Mapper 14 | public interface XxlJobLogGlueDao { 15 | 16 | public int save(XxlJobLogGlue xxlJobLogGlue); 17 | 18 | public List findByJobId(@Param("jobId") int jobId); 19 | 20 | public int removeOld(@Param("jobId") int jobId, @Param("limit") int limit); 21 | 22 | public int deleteByJobId(@Param("jobId") int jobId); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobLogReportDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobLogReport; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * job log 12 | * @author xuxueli 2019-11-22 13 | */ 14 | @Mapper 15 | public interface XxlJobLogReportDao { 16 | 17 | public int save(XxlJobLogReport xxlJobLogReport); 18 | 19 | public int update(XxlJobLogReport xxlJobLogReport); 20 | 21 | public List queryLogReport(@Param("triggerDayFrom") Date triggerDayFrom, 22 | @Param("triggerDayTo") Date triggerDayTo); 23 | 24 | public XxlJobLogReport queryLogReportTotal(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobRegistryDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobRegistry; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by xuxueli on 16/9/30. 12 | */ 13 | @Mapper 14 | public interface XxlJobRegistryDao { 15 | 16 | public List findDead(@Param("timeout") int timeout, 17 | @Param("nowTime") Date nowTime); 18 | 19 | public int removeDead(@Param("ids") List ids); 20 | 21 | public List findAll(@Param("timeout") int timeout, 22 | @Param("nowTime") Date nowTime); 23 | 24 | public int registryUpdate(@Param("registryGroup") String registryGroup, 25 | @Param("registryKey") String registryKey, 26 | @Param("registryValue") String registryValue, 27 | @Param("updateTime") Date updateTime); 28 | 29 | public int registrySave(@Param("registryGroup") String registryGroup, 30 | @Param("registryKey") String registryKey, 31 | @Param("registryValue") String registryValue, 32 | @Param("updateTime") Date updateTime); 33 | 34 | public int registryDelete(@Param("registryGroup") String registryGroup, 35 | @Param("registryKey") String registryKey, 36 | @Param("registryValue") String registryValue); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/dao/XxlJobUserDao.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.dao; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.XxlJobUser; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | import java.util.List; 7 | 8 | /** 9 | * @author xuxueli 2019-05-04 16:44:59 10 | */ 11 | @Mapper 12 | public interface XxlJobUserDao { 13 | 14 | public List pageList(@Param("offset") int offset, 15 | @Param("pagesize") int pagesize, 16 | @Param("username") String username, 17 | @Param("role") int role); 18 | public int pageListCount(@Param("offset") int offset, 19 | @Param("pagesize") int pagesize, 20 | @Param("username") String username, 21 | @Param("role") int role); 22 | 23 | public XxlJobUser loadByUserName(@Param("username") String username); 24 | 25 | public int save(XxlJobUser xxlJobUser); 26 | 27 | public int update(XxlJobUser xxlJobUser); 28 | 29 | public int delete(@Param("id") int id); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/service/PstDagJobRunRecordService.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.service; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobRunRecordInfo; 4 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public interface PstDagJobRunRecordService { 10 | 11 | /** 12 | * page list 13 | * 14 | * @param start 15 | * @param length 16 | * @return 17 | */ 18 | public Map pageList(int start, int length, String jobName, String jobDesc, int status); 19 | 20 | 21 | public List loadByRunRecord(String runRecord); 22 | 23 | public PstDagJobRunRecordInfo loadById( long id); 24 | /** 25 | * add job 26 | * 27 | * @param jobInfo 28 | * @return 29 | */ 30 | public ReturnT add(PstDagJobRunRecordInfo jobInfo); 31 | 32 | /** 33 | * update job 34 | * 35 | * @param jobInfo 36 | * @return 37 | */ 38 | public ReturnT update(PstDagJobRunRecordInfo jobInfo); 39 | 40 | 41 | 42 | /** 43 | * remove job 44 | * * 45 | * @param id 46 | * @return 47 | */ 48 | public ReturnT remove(int id); 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/service/PstDagJobService.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.service; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobInfo; 4 | import com.yueshuo.scheduler.admin.core.model.PstDagJobRunRecordInfo; 5 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public interface PstDagJobService { 11 | 12 | /** 13 | * page list 14 | * 15 | * @param start 16 | * @param length 17 | * @return 18 | */ 19 | public Map pageList(int start, int length, String jobName, String jobDesc, int status); 20 | 21 | /** 22 | * add job 23 | * 24 | * @param jobInfo 25 | * @return 26 | */ 27 | public ReturnT add(PstDagJobInfo jobInfo); 28 | 29 | /** 30 | * update job 31 | * 32 | * @param jobInfo 33 | * @return 34 | */ 35 | public ReturnT update(PstDagJobInfo jobInfo); 36 | 37 | /** 38 | * 更新dag调度依赖信息 39 | * @param jobInfo 40 | * @return 41 | */ 42 | public ReturnT updateDagInfo(PstDagJobInfo jobInfo); 43 | 44 | /** 45 | * remove job 46 | * * 47 | * @param id 48 | * @return 49 | */ 50 | public ReturnT remove(int id); 51 | 52 | /** 53 | * start job 54 | * 55 | * @param id 56 | * @return 57 | */ 58 | public ReturnT start(int id); 59 | 60 | /** 61 | * 执行 62 | * 63 | * @param id 64 | * @return 65 | */ 66 | public ReturnT trigger(int id); 67 | 68 | /** 69 | * 异常补偿执行 70 | * 71 | * @param jobId 72 | * @param record 73 | * @param type 74 | * @return 75 | */ 76 | public ReturnT triggerAgain(int jobId,String record,int type); 77 | 78 | /** 79 | * 执行一次 80 | * @param jobId 81 | * @return 82 | */ 83 | public ReturnT triggerOneTime(long dagJobId,int jobId,String record) ; 84 | 85 | /** 86 | * 跳过当前正在执行的job,直接执行下一级节点 87 | * @param jobId 88 | * @param record 89 | * @return 90 | */ 91 | public ReturnT SkipCurrStep(int jobId, String record) ; 92 | 93 | /** 94 | * stop job 95 | * 96 | * @param id 97 | * @return 98 | */ 99 | public ReturnT stop(int id); 100 | 101 | public PstDagJobInfo loadById(long id); 102 | 103 | public List loadRunDataTimeByDagJobId(long dagJobId,int size); 104 | } 105 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/service/XxlJobService.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.service; 2 | 3 | 4 | import com.yueshuo.scheduler.admin.core.model.XxlJobInfo; 5 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 6 | 7 | import java.util.Date; 8 | import java.util.Map; 9 | 10 | /** 11 | * core job action for xxl-job 12 | * 13 | * @author xuxueli 2016-5-28 15:30:33 14 | */ 15 | public interface XxlJobService { 16 | 17 | /** 18 | * page list 19 | * 20 | * @param start 21 | * @param length 22 | * @param jobGroup 23 | * @param jobDesc 24 | * @param executorHandler 25 | * @param author 26 | * @return 27 | */ 28 | public Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author); 29 | 30 | /** 31 | * add job 32 | * 33 | * @param jobInfo 34 | * @return 35 | */ 36 | public ReturnT add(XxlJobInfo jobInfo); 37 | 38 | /** 39 | * update job 40 | * 41 | * @param jobInfo 42 | * @return 43 | */ 44 | public ReturnT update(XxlJobInfo jobInfo); 45 | 46 | /** 47 | * remove job 48 | * * 49 | * @param id 50 | * @return 51 | */ 52 | public ReturnT remove(int id); 53 | 54 | /** 55 | * start job 56 | * 57 | * @param id 58 | * @return 59 | */ 60 | public ReturnT start(int id); 61 | 62 | /** 63 | * stop job 64 | * 65 | * @param id 66 | * @return 67 | */ 68 | public ReturnT stop(int id); 69 | 70 | /** 71 | * dashboard info 72 | * 73 | * @return 74 | */ 75 | public Map dashboardInfo(); 76 | 77 | /** 78 | * chart info 79 | * 80 | * @param startDate 81 | * @param endDate 82 | * @return 83 | */ 84 | public ReturnT> chartInfo(Date startDate, Date endDate); 85 | 86 | } 87 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/service/impl/AdminBizImpl.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.service.impl; 2 | 3 | import com.yueshuo.scheduler.admin.core.thread.JobCompleteHelper; 4 | import com.yueshuo.scheduler.admin.core.thread.JobRegistryHelper; 5 | import com.yueshuo.scheduler.core.biz.AdminBiz; 6 | import com.yueshuo.scheduler.core.biz.model.HandleCallbackParam; 7 | import com.yueshuo.scheduler.core.biz.model.RegistryParam; 8 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author xuxueli 2017-07-27 21:54:20 15 | */ 16 | @Service 17 | public class AdminBizImpl implements AdminBiz { 18 | 19 | 20 | @Override 21 | public ReturnT callback(List callbackParamList) { 22 | return JobCompleteHelper.getInstance().callback(callbackParamList); 23 | } 24 | 25 | @Override 26 | public ReturnT registry(RegistryParam registryParam) { 27 | return JobRegistryHelper.getInstance().registry(registryParam); 28 | } 29 | 30 | @Override 31 | public ReturnT registryRemove(RegistryParam registryParam) { 32 | return JobRegistryHelper.getInstance().registryRemove(registryParam); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/service/impl/PstDagJobRunRecordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.service.impl; 2 | 3 | import com.yueshuo.scheduler.admin.core.model.PstDagJobRunRecordInfo; 4 | import com.yueshuo.scheduler.admin.core.util.I18nUtil; 5 | import com.yueshuo.scheduler.admin.dao.PstDagJobRunRecordDao; 6 | import com.yueshuo.scheduler.admin.service.PstDagJobRunRecordService; 7 | import com.yueshuo.scheduler.core.biz.model.ReturnT; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.Date; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | @Service 17 | public class PstDagJobRunRecordServiceImpl implements PstDagJobRunRecordService { 18 | @Resource 19 | private PstDagJobRunRecordDao runRecordDao ; 20 | 21 | 22 | @Override 23 | public Map pageList(int start, int length, String jobName, String jobDesc, int status) { 24 | // page list 25 | List list = runRecordDao.pageList(start, length, jobName, jobDesc, status ); 26 | int list_count = runRecordDao.pageListCount(start, length, jobName, jobDesc, status); 27 | 28 | // package result 29 | Map maps = new HashMap(); 30 | maps.put("recordsTotal", list_count); // 总记录数 31 | maps.put("recordsFiltered", list_count); // 过滤后的总记录数 32 | maps.put("data", list); // 分页列表 33 | return maps; 34 | } 35 | 36 | @Override 37 | public List loadByRunRecord(String runRecord) { 38 | return runRecordDao.loadByRunRecord(runRecord); 39 | } 40 | 41 | @Override 42 | public PstDagJobRunRecordInfo loadById(long id) { 43 | return runRecordDao.loadById(id); 44 | } 45 | 46 | @Override 47 | public ReturnT add(PstDagJobRunRecordInfo jobInfo) { 48 | jobInfo.setCreateTime(new Date()); 49 | runRecordDao.save(jobInfo); 50 | if (jobInfo.getId() < 1) { 51 | return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) ); 52 | } 53 | 54 | return new ReturnT(String.valueOf(jobInfo.getId())); 55 | } 56 | 57 | @Override 58 | public ReturnT update(PstDagJobRunRecordInfo jobInfo) { 59 | return null; 60 | } 61 | 62 | 63 | @Override 64 | public ReturnT remove(int id) { 65 | return null; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/vo/Edge.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 边基本信息 7 | */ 8 | public class Edge implements Serializable { 9 | private String from ; 10 | private String to ; 11 | private String d ; 12 | private String id ; 13 | 14 | public String getId() { 15 | return id; 16 | } 17 | 18 | public void setId(String id) { 19 | this.id = id; 20 | } 21 | 22 | public String getD() { 23 | return d; 24 | } 25 | 26 | public void setD(String d) { 27 | this.d = d; 28 | } 29 | 30 | public String getFrom() { 31 | return from; 32 | } 33 | 34 | public void setFrom(String from) { 35 | this.from = from; 36 | } 37 | 38 | public String getTo() { 39 | return to; 40 | } 41 | 42 | public void setTo(String to) { 43 | this.to = to; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/vo/JobDagInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.vo; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | public class JobDagInfoVO implements Serializable { 7 | 8 | private long dagJobId ; 9 | private List nodes ; 10 | private List links ; 11 | private int runStatus = -1; 12 | private int nodeUnRuning = 0 ; 13 | private int nodeRuning = 0 ; 14 | private int nodeRunEnd = 0 ; 15 | private int nodeRunErr = 0 ; 16 | private int nodeRunLose = 0 ; 17 | private int queueSize ; 18 | 19 | public List getNodes() { 20 | return nodes; 21 | } 22 | 23 | public void setNodes(List nodes) { 24 | this.nodes = nodes; 25 | } 26 | 27 | public List getLinks() { 28 | return links; 29 | } 30 | 31 | public void setLinks(List links) { 32 | this.links = links; 33 | } 34 | 35 | public long getDagJobId() { 36 | return dagJobId; 37 | } 38 | 39 | public void setDagJobId(long dagJobId) { 40 | this.dagJobId = dagJobId; 41 | } 42 | 43 | public int getRunStatus() { 44 | return runStatus; 45 | } 46 | 47 | public void setRunStatus(int runStatus) { 48 | this.runStatus = runStatus; 49 | } 50 | 51 | public int getNodeUnRuning() { 52 | return nodeUnRuning; 53 | } 54 | 55 | public void setNodeUnRuning(int nodeUnRuning) { 56 | this.nodeUnRuning = nodeUnRuning; 57 | } 58 | 59 | public int getNodeRuning() { 60 | return nodeRuning; 61 | } 62 | 63 | public void setNodeRuning(int nodeRuning) { 64 | this.nodeRuning = nodeRuning; 65 | } 66 | 67 | public int getNodeRunEnd() { 68 | return nodeRunEnd; 69 | } 70 | 71 | public void setNodeRunEnd(int nodeRunEnd) { 72 | this.nodeRunEnd = nodeRunEnd; 73 | } 74 | 75 | public int getNodeRunErr() { 76 | return nodeRunErr; 77 | } 78 | 79 | public void setNodeRunErr(int nodeRunErr) { 80 | this.nodeRunErr = nodeRunErr; 81 | } 82 | 83 | public int getNodeRunLose() { 84 | return nodeRunLose; 85 | } 86 | 87 | public void setNodeRunLose(int nodeRunLose) { 88 | this.nodeRunLose = nodeRunLose; 89 | } 90 | 91 | public int getQueueSize() { 92 | return queueSize; 93 | } 94 | 95 | public void setQueueSize(int queueSize) { 96 | this.queueSize = queueSize; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/java/com/yueshuo/scheduler/admin/vo/Node.java: -------------------------------------------------------------------------------- 1 | package com.yueshuo.scheduler.admin.vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 节点基本信息 7 | */ 8 | public class Node implements Serializable { 9 | private String id ; 10 | private int dataId ; 11 | private String text ; 12 | private long taskId ; 13 | private float x ; 14 | private float y ; 15 | private int inputs ; 16 | private int outputs ; 17 | private int status = 0 ; 18 | private String record ; 19 | 20 | 21 | 22 | public String getId() { 23 | return id; 24 | } 25 | 26 | public void setId(String id) { 27 | this.id = id; 28 | } 29 | 30 | public int getDataId() { 31 | return dataId; 32 | } 33 | 34 | public void setDataId(int dataId) { 35 | this.dataId = dataId; 36 | } 37 | 38 | public String getText() { 39 | return text; 40 | } 41 | 42 | public void setText(String text) { 43 | this.text = text; 44 | } 45 | 46 | public long getTaskId() { 47 | return taskId; 48 | } 49 | 50 | public void setTaskId(long taskId) { 51 | this.taskId = taskId; 52 | } 53 | 54 | public float getX() { 55 | return x; 56 | } 57 | 58 | public void setX(float x) { 59 | this.x = x; 60 | } 61 | 62 | public float getY() { 63 | return y; 64 | } 65 | 66 | public void setY(float y) { 67 | this.y = y; 68 | } 69 | 70 | public int getInputs() { 71 | return inputs; 72 | } 73 | 74 | public void setInputs(int inputs) { 75 | this.inputs = inputs; 76 | } 77 | 78 | public int getOutputs() { 79 | return outputs; 80 | } 81 | 82 | public void setOutputs(int outputs) { 83 | this.outputs = outputs; 84 | } 85 | 86 | public int getStatus() { 87 | return status; 88 | } 89 | 90 | public void setStatus(int status) { 91 | this.status = status; 92 | } 93 | 94 | public String getRecord() { 95 | return record; 96 | } 97 | 98 | public void setRecord(String record) { 99 | this.record = record; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ### web 2 | server.port=8181 3 | server.servlet.context-path=/xxl-job-admin 4 | 5 | ### actuator 6 | management.server.servlet.context-path=/actuator 7 | management.health.mail.enabled=false 8 | 9 | ### resources 10 | spring.mvc.servlet.load-on-startup=0 11 | spring.mvc.static-path-pattern=/static/** 12 | spring.resources.static-locations=classpath:/static/ 13 | 14 | ### freemarker 15 | spring.freemarker.templateLoaderPath=classpath:/templates/ 16 | spring.freemarker.suffix=.ftl 17 | spring.freemarker.charset=UTF-8 18 | spring.freemarker.request-context-attribute=request 19 | spring.freemarker.settings.number_format=0.########## 20 | 21 | ### mybatis 22 | mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml 23 | #mybatis.type-aliases-package=com.yueshuo.scheduler.admin.core.model 24 | 25 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai 26 | spring.datasource.username=root 27 | spring.datasource.password=clearlove7 28 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 29 | 30 | ### datasource-pool 31 | spring.datasource.type=com.zaxxer.hikari.HikariDataSource 32 | spring.datasource.hikari.minimum-idle=10 33 | spring.datasource.hikari.maximum-pool-size=30 34 | spring.datasource.hikari.auto-commit=true 35 | spring.datasource.hikari.idle-timeout=30000 36 | spring.datasource.hikari.pool-name=HikariCP 37 | spring.datasource.hikari.max-lifetime=900000 38 | spring.datasource.hikari.connection-timeout=10000 39 | spring.datasource.hikari.connection-test-query=SELECT 1 40 | spring.datasource.hikari.validation-timeout=1000 41 | 42 | ### xxl-job, email 43 | spring.mail.host=smtp.qq.com 44 | spring.mail.port=25 45 | spring.mail.username=123456@qq.com 46 | spring.mail.from=123456@qq.com 47 | spring.mail.password=123456 48 | spring.mail.properties.mail.smtp.auth=true 49 | spring.mail.properties.mail.smtp.starttls.enable=true 50 | spring.mail.properties.mail.smtp.starttls.required=true 51 | spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory 52 | 53 | ### xxl-job, access token 54 | xxl.job.accessToken= 55 | 56 | ### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en") 57 | xxl.job.i18n=zh_CN 58 | 59 | ## xxl-job, triggerpool max size 60 | xxl.job.triggerpool.fast.max=200 61 | xxl.job.triggerpool.slow.max=100 62 | 63 | ### xxl-job, log retention days 64 | xxl.job.logretentiondays=30 65 | 66 | 67 | logger.level=INFO 68 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logback 5 | 6 | 7 | 8 | 9 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 10 | 11 | 12 | 13 | 14 | ${log.path} 15 | 16 | ${log.path}.%d{yyyy-MM-dd}.zip 17 | 18 | 19 | %date %level [%thread] %logger{36} [%file : %line] %msg%n 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | t.id, 18 | t.job_id, 19 | t.glue_type, 20 | t.glue_source, 21 | t.glue_remark, 22 | t.add_time, 23 | t.update_time 24 | 25 | 26 | 27 | INSERT INTO xxl_job_logglue ( 28 | `job_id`, 29 | `glue_type`, 30 | `glue_source`, 31 | `glue_remark`, 32 | `add_time`, 33 | `update_time` 34 | ) VALUES ( 35 | #{jobId}, 36 | #{glueType}, 37 | #{glueSource}, 38 | #{glueRemark}, 39 | #{addTime}, 40 | #{updateTime} 41 | ); 42 | 45 | 46 | 47 | 53 | 54 | 55 | DELETE FROM xxl_job_logglue 56 | WHERE id NOT in( 57 | SELECT id FROM( 58 | SELECT id FROM xxl_job_logglue 59 | WHERE `job_id` = #{jobId} 60 | ORDER BY update_time desc 61 | LIMIT 0, #{limit} 62 | ) t1 63 | ) AND `job_id` = #{jobId} 64 | 65 | 66 | 67 | DELETE FROM xxl_job_logglue 68 | WHERE `job_id` = #{jobId} 69 | 70 | 71 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/mybatis-mapper/XxlJobLogReportMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | t.id, 16 | t.trigger_day, 17 | t.running_count, 18 | t.suc_count, 19 | t.fail_count 20 | 21 | 22 | 23 | INSERT INTO xxl_job_log_report ( 24 | `trigger_day`, 25 | `running_count`, 26 | `suc_count`, 27 | `fail_count` 28 | ) VALUES ( 29 | #{triggerDay}, 30 | #{runningCount}, 31 | #{sucCount}, 32 | #{failCount} 33 | ); 34 | 37 | 38 | 39 | 40 | UPDATE xxl_job_log_report 41 | SET `running_count` = #{runningCount}, 42 | `suc_count` = #{sucCount}, 43 | `fail_count` = #{failCount} 44 | WHERE `trigger_day` = #{triggerDay} 45 | 46 | 47 | 53 | 54 | 61 | 62 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/mybatis-mapper/XxlJobRegistryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | t.id, 16 | t.registry_group, 17 | t.registry_key, 18 | t.registry_value, 19 | t.update_time 20 | 21 | 22 | 27 | 28 | 29 | DELETE FROM xxl_job_registry 30 | WHERE id in 31 | 32 | #{item} 33 | 34 | 35 | 36 | 41 | 42 | 43 | UPDATE xxl_job_registry 44 | SET `update_time` = #{updateTime} 45 | WHERE `registry_group` = #{registryGroup} 46 | AND `registry_key` = #{registryKey} 47 | AND `registry_value` = #{registryValue} 48 | 49 | 50 | 51 | INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`) 52 | VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime}) 53 | 54 | 55 | 56 | DELETE FROM xxl_job_registry 57 | WHERE registry_group = #{registryGroup} 58 | AND registry_key = #{registryKey} 59 | AND registry_value = #{registryValue} 60 | 61 | 62 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | t.id, 16 | t.username, 17 | t.password, 18 | t.role, 19 | t.permission 20 | 21 | 22 | 36 | 37 | 49 | 50 | 55 | 56 | 57 | INSERT INTO xxl_job_user ( 58 | username, 59 | password, 60 | role, 61 | permission 62 | ) VALUES ( 63 | #{username}, 64 | #{password}, 65 | #{role}, 66 | #{permission} 67 | ); 68 | 69 | 70 | 71 | UPDATE xxl_job_user 72 | SET 73 | 74 | password = #{password}, 75 | 76 | role = #{role}, 77 | permission = #{permission} 78 | WHERE id = #{id} 79 | 80 | 81 | 82 | DELETE 83 | FROM xxl_job_user 84 | WHERE id = #{id} 85 | 86 | 87 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.eot -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.ttf -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/Ionicons/fonts/ionicons.woff -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/PACE/themes/blue/pace-theme-flash.css: -------------------------------------------------------------------------------- 1 | /* This is a compiled file, you should be editing the file in the templates directory */ 2 | .pace { 3 | -webkit-pointer-events: none; 4 | pointer-events: none; 5 | -webkit-user-select: none; 6 | -moz-user-select: none; 7 | user-select: none; 8 | } 9 | 10 | .pace-inactive { 11 | display: none; 12 | } 13 | 14 | .pace .pace-progress { 15 | background: #2299dd; 16 | position: fixed; 17 | z-index: 2000; 18 | top: 0; 19 | right: 100%; 20 | width: 100%; 21 | height: 2px; 22 | } 23 | 24 | .pace .pace-progress-inner { 25 | display: block; 26 | position: absolute; 27 | right: 0px; 28 | width: 100px; 29 | height: 100%; 30 | box-shadow: 0 0 10px #2299dd, 0 0 5px #2299dd; 31 | opacity: 1.0; 32 | -webkit-transform: rotate(3deg) translate(0px, -4px); 33 | -moz-transform: rotate(3deg) translate(0px, -4px); 34 | -ms-transform: rotate(3deg) translate(0px, -4px); 35 | -o-transform: rotate(3deg) translate(0px, -4px); 36 | transform: rotate(3deg) translate(0px, -4px); 37 | } 38 | 39 | .pace .pace-activity { 40 | display: block; 41 | position: fixed; 42 | z-index: 2000; 43 | top: 15px; 44 | right: 15px; 45 | width: 14px; 46 | height: 14px; 47 | border: solid 2px transparent; 48 | border-top-color: #2299dd; 49 | border-left-color: #2299dd; 50 | border-radius: 10px; 51 | -webkit-animation: pace-spinner 400ms linear infinite; 52 | -moz-animation: pace-spinner 400ms linear infinite; 53 | -ms-animation: pace-spinner 400ms linear infinite; 54 | -o-animation: pace-spinner 400ms linear infinite; 55 | animation: pace-spinner 400ms linear infinite; 56 | } 57 | 58 | @-webkit-keyframes pace-spinner { 59 | 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 60 | 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } 61 | } 62 | @-moz-keyframes pace-spinner { 63 | 0% { -moz-transform: rotate(0deg); transform: rotate(0deg); } 64 | 100% { -moz-transform: rotate(360deg); transform: rotate(360deg); } 65 | } 66 | @-o-keyframes pace-spinner { 67 | 0% { -o-transform: rotate(0deg); transform: rotate(0deg); } 68 | 100% { -o-transform: rotate(360deg); transform: rotate(360deg); } 69 | } 70 | @-ms-keyframes pace-spinner { 71 | 0% { -ms-transform: rotate(0deg); transform: rotate(0deg); } 72 | 100% { -ms-transform: rotate(360deg); transform: rotate(360deg); } 73 | } 74 | @keyframes pace-spinner { 75 | 0% { transform: rotate(0deg); transform: rotate(0deg); } 76 | 100% { transform: rotate(360deg); transform: rotate(360deg); } 77 | } 78 | -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/to-be-experts/easy-task-scheduler/be040b39f937546aaa04d668d8872740b8cf64cd/scheduler-admin/src/main/resources/static/adminlte/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /scheduler-admin/src/main/resources/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 3 integration 3 | ©2011-2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes, 6 | {sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")}; 7 | l=0;for(h=f.length;l",{"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#", 8 | "aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('