소스 검색

新增调度,仪表盘

xueli.xue 8 년 전
부모
커밋
6e3e24a909

+ 1 - 2
README.md 파일 보기

780
 - 3、任务权限管理;
780
 - 3、任务权限管理;
781
 - 4、执行器,server启动,注册逻辑调整;
781
 - 4、执行器,server启动,注册逻辑调整;
782
 - 5、调度失败重试机制;
782
 - 5、调度失败重试机制;
783
-
784
-- 7、JobHandler开启多线程时,支持记录执行日志;
783
+- 6、JobHandler开启多线程时,支持记录执行日志;
785
 
784
 
786
 
785
 
787
 ## 七、其他
786
 ## 七、其他

+ 17 - 6
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java 파일 보기

3
 import com.xxl.job.admin.controller.annotation.PermessionLimit;
3
 import com.xxl.job.admin.controller.annotation.PermessionLimit;
4
 import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
4
 import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
5
 import com.xxl.job.admin.core.util.PropertiesUtil;
5
 import com.xxl.job.admin.core.util.PropertiesUtil;
6
+import com.xxl.job.admin.service.IXxlJobService;
6
 import com.xxl.job.core.biz.model.ReturnT;
7
 import com.xxl.job.core.biz.model.ReturnT;
7
 import org.apache.commons.lang.StringUtils;
8
 import org.apache.commons.lang.StringUtils;
8
 import org.springframework.stereotype.Controller;
9
 import org.springframework.stereotype.Controller;
11
 import org.springframework.web.bind.annotation.RequestMethod;
12
 import org.springframework.web.bind.annotation.RequestMethod;
12
 import org.springframework.web.bind.annotation.ResponseBody;
13
 import org.springframework.web.bind.annotation.ResponseBody;
13
 
14
 
15
+import javax.annotation.Resource;
14
 import javax.servlet.http.HttpServletRequest;
16
 import javax.servlet.http.HttpServletRequest;
15
 import javax.servlet.http.HttpServletResponse;
17
 import javax.servlet.http.HttpServletResponse;
18
+import java.util.Map;
16
 
19
 
17
 /**
20
 /**
18
  * index controller
21
  * index controller
21
 @Controller
24
 @Controller
22
 public class IndexController {
25
 public class IndexController {
23
 
26
 
27
+	@Resource
28
+	private IXxlJobService xxlJobService;
29
+
24
 	@RequestMapping("/")
30
 	@RequestMapping("/")
25
-	@PermessionLimit(limit=false)
26
-	public String index(Model model, HttpServletRequest request) {
27
-		if (!PermissionInterceptor.ifLogin(request)) {
28
-			return "redirect:/toLogin";
29
-		}
30
-		return "redirect:/jobinfo";
31
+	public String index(Model model) {
32
+
33
+		Map<String, Object> dashboardMap = xxlJobService.dashboardInfo();
34
+		model.addAllAttributes(dashboardMap);
35
+
36
+		return "index";
31
 	}
37
 	}
32
 	
38
 	
33
 	@RequestMapping("/toLogin")
39
 	@RequestMapping("/toLogin")
71
 	
77
 	
72
 	@RequestMapping("/help")
78
 	@RequestMapping("/help")
73
 	public String help() {
79
 	public String help() {
80
+
81
+		/*if (!PermissionInterceptor.ifLogin(request)) {
82
+			return "redirect:/toLogin";
83
+		}*/
84
+
74
 		return "help";
85
 		return "help";
75
 	}
86
 	}
76
 	
87
 	

+ 6 - 4
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java 파일 보기

120
 			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
120
 			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
121
 
121
 
122
 			// is end
122
 			// is end
123
-			/*XxlJobLog jobLog = xxlJobLogDao.load(logId);
124
-			if (jobLog.getHandleCode() > 0) {
125
-				logResult.getContent().setEnd(true);
126
-			}*/
123
+            if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
124
+                XxlJobLog jobLog = xxlJobLogDao.load(logId);
125
+                if (jobLog.getHandleCode() > 0) {
126
+                    logResult.getContent().setEnd(true);
127
+                }
128
+            }
127
 
129
 
128
 			return logResult;
130
 			return logResult;
129
 		} catch (Exception e) {
131
 		} catch (Exception e) {

+ 3 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobInfoDao.java 파일 보기

23
 	public int delete(int id);
23
 	public int delete(int id);
24
 
24
 
25
 	public List<XxlJobInfo> getJobsByGroup(String jobGroup);
25
 	public List<XxlJobInfo> getJobsByGroup(String jobGroup);
26
+
27
+	public int findAllCount();
28
+
26
 }
29
 }

+ 3 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobLogDao.java 파일 보기

23
 	public int updateHandleInfo(XxlJobLog xxlJobLog);
23
 	public int updateHandleInfo(XxlJobLog xxlJobLog);
24
 	
24
 	
25
 	public int delete(int jobId);
25
 	public int delete(int jobId);
26
-	
26
+
27
+	public int findByHandleCodeCount(int handleCode);
28
+
27
 }
29
 }

+ 5 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobInfoDaoImpl.java 파일 보기

66
 		return sqlSessionTemplate.selectList("XxlJobInfoMapper.getJobsByGroup", jobGroup);
66
 		return sqlSessionTemplate.selectList("XxlJobInfoMapper.getJobsByGroup", jobGroup);
67
 	}
67
 	}
68
 
68
 
69
+	@Override
70
+	public int findAllCount() {
71
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.findAllCount");
72
+	}
73
+
69
 }
74
 }

+ 6 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobLogDaoImpl.java 파일 보기

76
 	public int delete(int jobId) {
76
 	public int delete(int jobId) {
77
 		return sqlSessionTemplate.delete("XxlJobLogMapper.delete", jobId);
77
 		return sqlSessionTemplate.delete("XxlJobLogMapper.delete", jobId);
78
 	}
78
 	}
79
-	
79
+
80
+	@Override
81
+	public int findByHandleCodeCount(int handleCode) {
82
+		return sqlSessionTemplate.selectOne("XxlJobLogMapper.findByHandleCodeCount", handleCode);
83
+	}
84
+
80
 }
85
 }

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java 파일 보기

26
 	public ReturnT<String> resume(int id);
26
 	public ReturnT<String> resume(int id);
27
 	
27
 	
28
 	public ReturnT<String> triggerJob(int id);
28
 	public ReturnT<String> triggerJob(int id);
29
-	
29
+
30
+    Map<String,Object> dashboardInfo();
30
 }
31
 }

+ 41 - 8
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java 파일 보기

4
 import com.xxl.job.admin.core.model.XxlJobInfo;
4
 import com.xxl.job.admin.core.model.XxlJobInfo;
5
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
5
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
6
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
6
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
7
-import com.xxl.job.admin.dao.IXxlJobGroupDao;
8
-import com.xxl.job.admin.dao.IXxlJobInfoDao;
9
-import com.xxl.job.admin.dao.IXxlJobLogDao;
10
-import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
7
+import com.xxl.job.admin.core.thread.JobRegistryHelper;
8
+import com.xxl.job.admin.dao.*;
11
 import com.xxl.job.admin.service.IXxlJobService;
9
 import com.xxl.job.admin.service.IXxlJobService;
12
 import com.xxl.job.core.biz.model.ReturnT;
10
 import com.xxl.job.core.biz.model.ReturnT;
11
+import com.xxl.job.core.registry.RegistHelper;
12
+import org.apache.commons.collections.CollectionUtils;
13
 import org.apache.commons.lang.StringUtils;
13
 import org.apache.commons.lang.StringUtils;
14
 import org.quartz.CronExpression;
14
 import org.quartz.CronExpression;
15
 import org.quartz.SchedulerException;
15
 import org.quartz.SchedulerException;
19
 
19
 
20
 import javax.annotation.Resource;
20
 import javax.annotation.Resource;
21
 import java.text.MessageFormat;
21
 import java.text.MessageFormat;
22
-import java.util.HashMap;
23
-import java.util.List;
24
-import java.util.Map;
22
+import java.util.*;
25
 
23
 
26
 /**
24
 /**
27
  * core job action for xxl-job
25
  * core job action for xxl-job
257
 			return ReturnT.FAIL;
255
 			return ReturnT.FAIL;
258
 		}
256
 		}
259
 	}
257
 	}
260
-	
258
+
259
+	@Override
260
+	public Map<String, Object> dashboardInfo() {
261
+
262
+		int jobInfoCount = xxlJobInfoDao.findAllCount();
263
+		int jobLogCount = xxlJobLogDao.findByHandleCodeCount(-1);
264
+		int jobLogSuccessCount = xxlJobLogDao.findByHandleCodeCount(ReturnT.SUCCESS_CODE);
265
+
266
+		// executor count
267
+		Set<String> executerAddressSet = new HashSet<String>();
268
+		List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
269
+		if (CollectionUtils.isNotEmpty(groupList)) {
270
+			for (XxlJobGroup group: groupList) {
271
+				List<String> registryList = null;
272
+				if (group.getAddressType() == 0) {
273
+					registryList = JobRegistryHelper.discover(RegistHelper.RegistType.EXECUTOR.name(), group.getAppName());
274
+				} else {
275
+					if (StringUtils.isNotBlank(group.getAddressList())) {
276
+						registryList = Arrays.asList(group.getAddressList().split(","));
277
+					}
278
+				}
279
+				if (CollectionUtils.isNotEmpty(registryList)) {
280
+					executerAddressSet.addAll(registryList);
281
+				}
282
+			}
283
+		}
284
+		int executorCount = executerAddressSet.size();
285
+
286
+		Map<String, Object> dashboardMap = new HashMap<String, Object>();
287
+		dashboardMap.put("jobInfoCount", jobInfoCount);
288
+		dashboardMap.put("jobLogCount", jobLogCount);
289
+		dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount);
290
+		dashboardMap.put("executorCount", executorCount);
291
+		return dashboardMap;
292
+	}
293
+
261
 }
294
 }

+ 6 - 1
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml 파일 보기

151
 		FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
151
 		FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
152
 		WHERE t.job_group = #{jobGroup}
152
 		WHERE t.job_group = #{jobGroup}
153
 	</select>
153
 	</select>
154
-	
154
+
155
+	<select id="findAllCount" resultType="int">
156
+		SELECT count(1)
157
+		FROM XXL_JOB_QRTZ_TRIGGER_INFO
158
+	</select>
159
+
155
 </mapper>
160
 </mapper>

+ 10 - 0
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml 파일 보기

123
 		delete from XXL_JOB_QRTZ_TRIGGER_LOG
123
 		delete from XXL_JOB_QRTZ_TRIGGER_LOG
124
 		WHERE job_id = #{jobId}
124
 		WHERE job_id = #{jobId}
125
 	</delete>
125
 	</delete>
126
+
127
+	<select id="findByHandleCodeCount" parameterType="java.lang.Integer" resultType="java.lang.Integer">
128
+		SELECT count(1)
129
+		FROM XXL_JOB_QRTZ_TRIGGER_LOG AS t
130
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
131
+			<if test="_parameter gt 0">
132
+				AND t.handle_code = #{handleCode}
133
+			</if>
134
+		</trim>
135
+	</select>
126
 	
136
 	
127
 </mapper>
137
 </mapper>

+ 3 - 3
xxl-job-admin/src/main/webapp/WEB-INF/template/common/common.macro.ftl 파일 보기

81
 			<!-- sidebar menu: : style can be found in sidebar.less -->
81
 			<!-- sidebar menu: : style can be found in sidebar.less -->
82
 			<ul class="sidebar-menu">
82
 			<ul class="sidebar-menu">
83
 				<li class="header">常用模块</li>
83
 				<li class="header">常用模块</li>
84
-				<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li>
84
+				<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-aqua"></i> <span>任务管理</span></a></li>
85
 				<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-yellow"></i><span>调度日志</span></a></li>
85
 				<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-yellow"></i><span>调度日志</span></a></li>
86
-                <li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-aqua"></i> <span>执行器管理</span></a></li>
87
-				<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-red"></i><span>使用教程</span></a></li>
86
+                <li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-green"></i> <span>执行器管理</span></a></li>
87
+				<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-gray"></i><span>使用教程</span></a></li>
88
 			</ul>
88
 			</ul>
89
 		</section>
89
 		</section>
90
 		<!-- /.sidebar -->
90
 		<!-- /.sidebar -->

+ 100 - 0
xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl 파일 보기

1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+  	<title>任务调度中心</title>
5
+  	<#import "/common/common.macro.ftl" as netCommon>
6
+	<@netCommon.commonStyle />
7
+</head>
8
+<body class="hold-transition skin-blue sidebar-mini <#if cookieMap?exists && "off" == cookieMap["adminlte_settings"].value >sidebar-collapse</#if> ">
9
+<div class="wrapper">
10
+	<!-- header -->
11
+	<@netCommon.commonHeader />
12
+	<!-- left -->
13
+	<@netCommon.commonLeft "index" />
14
+	
15
+	<!-- Content Wrapper. Contains page content -->
16
+	<div class="content-wrapper">
17
+		<!-- Content Header (Page header) -->
18
+		<section class="content-header">
19
+			<h1>仪表盘<small>任务调度中心</small></h1>
20
+			<!--
21
+			<ol class="breadcrumb">
22
+				<li><a><i class="fa fa-dashboard"></i>调度中心</a></li>
23
+				<li class="active">使用教程</li>
24
+			</ol>
25
+			-->
26
+		</section>
27
+
28
+		<!-- Main content -->
29
+		<section class="content">
30
+
31
+            <!-- 简要报表 -->
32
+            <div class="row">
33
+
34
+                <#-- 任务信息 -->
35
+                <div class="col-md-4 col-sm-6 col-xs-12">
36
+                    <div class="info-box bg-aqua">
37
+                        <span class="info-box-icon"><i class="fa fa-flag-o"></i></span>
38
+
39
+                        <div class="info-box-content">
40
+                            <span class="info-box-text">任务数量</span>
41
+                            <span class="info-box-number">${jobInfoCount}</span>
42
+
43
+                            <div class="progress">
44
+                                <div class="progress-bar" style="width: 100%"></div>
45
+                            </div>
46
+                            <span class="progress-description">系统中配置的任务数量</span>
47
+                        </div>
48
+                    </div>
49
+                </div>
50
+
51
+                <#-- 调度信息 -->
52
+                <div class="col-md-4 col-sm-6 col-xs-12">
53
+                    <div class="info-box bg-yellow">
54
+                        <span class="info-box-icon"><i class="fa fa-calendar"></i></span>
55
+
56
+                        <div class="info-box-content">
57
+                            <span class="info-box-text">调度次数</span>
58
+                            <span class="info-box-number">${jobLogCount}</span>
59
+
60
+                            <div class="progress">
61
+                                <div class="progress-bar" style="width: ${(jobLogSuccessCount*100/jobLogCount)?string("0.00")}%"></div>
62
+                            </div>
63
+                            <span class="progress-description">
64
+                                调度成功率:${(jobLogSuccessCount*100/jobLogCount)?string("0.00")}<small>%</small>
65
+                            </span>
66
+                        </div>
67
+                    </div>
68
+                </div>
69
+
70
+                <#-- 执行器 -->
71
+                <div class="col-md-4 col-sm-6 col-xs-12">
72
+                    <div class="info-box bg-green">
73
+                        <span class="info-box-icon"><i class="fa fa-thumbs-o-up"></i></span>
74
+
75
+                        <div class="info-box-content">
76
+                            <span class="info-box-text">执行器数量</span>
77
+                            <span class="info-box-number">${executorCount}</span>
78
+
79
+                            <div class="progress">
80
+                                <div class="progress-bar" style="width: 100%"></div>
81
+                            </div>
82
+                            <span class="progress-description">心跳检测成功的执行器机器数量</span>
83
+                        </div>
84
+                    </div>
85
+                </div>
86
+
87
+            </div>
88
+            <!-- /.row -->
89
+
90
+		</section>
91
+		<!-- /.content -->
92
+	</div>
93
+	<!-- /.content-wrapper -->
94
+	
95
+	<!-- footer -->
96
+	<@netCommon.commonFooter />
97
+</div>
98
+<@netCommon.commonScript />
99
+</body>
100
+</html>

+ 1 - 1
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl 파일 보기

25
 	<div class="content-wrapper">
25
 	<div class="content-wrapper">
26
 		<!-- Content Header (Page header) -->
26
 		<!-- Content Header (Page header) -->
27
 		<section class="content-header">
27
 		<section class="content-header">
28
-			<h1>调度管理<small>任务调度中心</small></h1>
28
+			<h1>任务管理<small>任务调度中心</small></h1>
29
 			<!--
29
 			<!--
30
 			<ol class="breadcrumb">
30
 			<ol class="breadcrumb">
31
 				<li><a><i class="fa fa-dashboard"></i>调度管理</a></li>
31
 				<li><a><i class="fa fa-dashboard"></i>调度管理</a></li>

+ 1 - 1
xxl-job-admin/src/main/webapp/static/js/joblog.detail.1.js 파일 보기

47
 
47
 
48
                         // valid end
48
                         // valid end
49
                         if (data.content.end) {
49
                         if (data.content.end) {
50
-                            logRunStop('<span style="color: green;">[Rolling Log Finish]</span>');
50
+                            logRunStop('<br><span style="color: green;">[Rolling Log Finish]</span>');
51
                             return;
51
                             return;
52
                         }
52
                         }
53
 
53