Przeglądaj źródła

review job helper

kerry 5 lat temu
rodzic
commit
b5065c71cc

+ 61 - 62
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java Wyświetl plik

@@ -49,79 +49,78 @@ public class JobFailMonitorHelper {
49 49
      */
50 50
     @PostConstruct
51 51
     public void start() {
52
-        monitorThread = new Thread(new Runnable() {
53
-
54
-            @Override
55
-            public void run() {
56
-
57
-                // monitor
58
-                while (!toStop) {
59
-                    try {
60
-
61
-                        List<Long> failLogIds = xxlJobLogDao.findFailJobLogIds(1000);
62
-                        if (failLogIds != null && !failLogIds.isEmpty()) {
63
-                            for (long failLogId : failLogIds) {
64
-
65
-                                // lock log
66
-                                int lockRet = xxlJobLogDao.updateAlarmStatus(failLogId, 0, -1);
67
-                                if (lockRet < 1) {
68
-                                    continue;
69
-                                }
70
-                                XxlJobLog log = xxlJobLogDao.load(failLogId);
71
-                                XxlJobInfo info = xxlJobInfoDao.loadById(log.getJobId());
72
-
73
-                                // 1、fail retry monitor
74
-                                if (log.getExecutorFailRetryCount() > 0) {
75
-                                    jobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount() - 1), log.getExecutorShardingParam(), log.getExecutorParam());
76
-                                    String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_type_retry") + "<<<<<<<<<<< </span><br>";
77
-                                    log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
78
-                                    xxlJobLogDao.updateTriggerInfo(log);
79
-                                }
80
-
81
-                                // 2、fail alarm monitor
82
-                                int newAlarmStatus = 0;        // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
83
-                                if (info != null && info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) {
84
-                                    boolean alarmResult = true;
85
-                                    try {
86
-                                        alarmResult = failAlarm(info, log);
87
-                                    } catch (Exception e) {
88
-                                        alarmResult = false;
89
-                                        logger.error(e.getMessage(), e);
90
-                                    }
91
-                                    newAlarmStatus = alarmResult ? 2 : 3;
92
-                                } else {
93
-                                    newAlarmStatus = 1;
94
-                                }
95
-
96
-                                xxlJobLogDao.updateAlarmStatus(failLogId, -1, newAlarmStatus);
97
-                            }
98
-                        }
52
+        monitorThread = new Thread(this::failJobMonitor);
53
+        monitorThread.setDaemon(true);
54
+        monitorThread.setName("jobAdminFailMonitorHp");
55
+        //monitorThread.setName("xxl-job, admin JobFailMonitorHelper");
56
+        monitorThread.start();
57
+    }
58
+
99 59
 
100
-                    } catch (Exception e) {
101
-                        if (!toStop) {
102
-                            logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
60
+    private void failJobMonitor() {
61
+        // monitor
62
+        while (!toStop) {
63
+            try {
64
+                List<Long> failLogIds = xxlJobLogDao.findFailJobLogIds(1000);
65
+                if (failLogIds != null && !failLogIds.isEmpty()) {
66
+                    for (long failLogId : failLogIds) {
67
+
68
+                        // lock log
69
+                        int lockRet = xxlJobLogDao.updateAlarmStatus(failLogId, 0, -1);
70
+                        if (lockRet < 1) {
71
+                            continue;
72
+                        }
73
+                        XxlJobLog log = xxlJobLogDao.load(failLogId);
74
+                        XxlJobInfo info = xxlJobInfoDao.loadById(log.getJobId());
75
+
76
+                        // 1、fail retry monitor
77
+                        if (log.getExecutorFailRetryCount() > 0) {
78
+                            jobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount() - 1), log.getExecutorShardingParam(), log.getExecutorParam());
79
+                            String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_type_retry") + "<<<<<<<<<<< </span><br>";
80
+                            log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
81
+                            xxlJobLogDao.updateTriggerInfo(log);
103 82
                         }
104
-                    }
105 83
 
106
-                    try {
107
-                        TimeUnit.SECONDS.sleep(10);
108
-                    } catch (Exception e) {
109
-                        if (!toStop) {
110
-                            logger.error(e.getMessage(), e);
84
+                        // 2、fail alarm monitor
85
+                        int newAlarmStatus = 0;        // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
86
+                        if (info != null && info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) {
87
+                            boolean alarmResult = true;
88
+                            try {
89
+                                alarmResult = failAlarm(info, log);
90
+                            } catch (Exception e) {
91
+                                alarmResult = false;
92
+                                logger.error(e.getMessage(), e);
93
+                            }
94
+                            newAlarmStatus = alarmResult ? 2 : 3;
95
+                        } else {
96
+                            newAlarmStatus = 1;
111 97
                         }
112
-                    }
113 98
 
99
+                        xxlJobLogDao.updateAlarmStatus(failLogId, -1, newAlarmStatus);
100
+                    }
114 101
                 }
115 102
 
116
-                logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop");
103
+            } catch (Exception e) {
104
+                if (!toStop) {
105
+                    logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
106
+                }
107
+            }
117 108
 
109
+            try {
110
+                TimeUnit.SECONDS.sleep(10);
111
+            } catch (Exception e) {
112
+                if (!toStop) {
113
+                    logger.error(e.getMessage(), e);
114
+                }
118 115
             }
119
-        });
120
-        monitorThread.setDaemon(true);
121
-        monitorThread.setName("xxl-job, admin JobFailMonitorHelper");
122
-        monitorThread.start();
116
+
117
+        }
118
+
119
+        logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop");
120
+
123 121
     }
124 122
 
123
+
125 124
     @PreDestroy
126 125
     public void toStop() {
127 126
         toStop = true;

+ 85 - 82
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobLogReportHelper.java Wyświetl plik

@@ -46,112 +46,115 @@ public class JobLogReportHelper {
46 46
     @PostConstruct
47 47
     public void start() {
48 48
         logrThread = new Thread(new Runnable() {
49
-
50 49
             @Override
51 50
             public void run() {
52
-
53
-                // last clean log time
54
-                long lastCleanLogTime = 0;
51
+                jobLogReport();
52
+            }
53
+        });
54
+        logrThread.setDaemon(true);
55
+        logrThread.setName("xxl-job, admin JobLogReportHelper");
56
+        logrThread.start();
57
+    }
55 58
 
56 59
 
57
-                while (!toStop) {
60
+    private void jobLogReport() {
61
+        // last clean log time
62
+        long lastCleanLogTime = 0;
58 63
 
59
-                    // 1、log-report refresh: refresh log report in 3 days
60
-                    try {
61 64
 
62
-                        for (int i = 0; i < 3; i++) {
65
+        while (!toStop) {
63 66
 
64
-                            // today
65
-                            Calendar itemDay = Calendar.getInstance();
66
-                            itemDay.add(Calendar.DAY_OF_MONTH, -i);
67
-                            itemDay.set(Calendar.HOUR_OF_DAY, 0);
68
-                            itemDay.set(Calendar.MINUTE, 0);
69
-                            itemDay.set(Calendar.SECOND, 0);
70
-                            itemDay.set(Calendar.MILLISECOND, 0);
67
+            // 1、log-report refresh: refresh log report in 3 days
68
+            try {
71 69
 
72
-                            Date todayFrom = itemDay.getTime();
70
+                for (int i = 0; i < 3; i++) {
73 71
 
74
-                            itemDay.set(Calendar.HOUR_OF_DAY, 23);
75
-                            itemDay.set(Calendar.MINUTE, 59);
76
-                            itemDay.set(Calendar.SECOND, 59);
77
-                            itemDay.set(Calendar.MILLISECOND, 999);
72
+                    // today
73
+                    Calendar itemDay = Calendar.getInstance();
74
+                    itemDay.add(Calendar.DAY_OF_MONTH, -i);
75
+                    itemDay.set(Calendar.HOUR_OF_DAY, 0);
76
+                    itemDay.set(Calendar.MINUTE, 0);
77
+                    itemDay.set(Calendar.SECOND, 0);
78
+                    itemDay.set(Calendar.MILLISECOND, 0);
78 79
 
79
-                            Date todayTo = itemDay.getTime();
80
+                    Date todayFrom = itemDay.getTime();
80 81
 
81
-                            // refresh log-report every minute
82
-                            XxlJobLogReport xxlJobLogReport = new XxlJobLogReport();
83
-                            xxlJobLogReport.setTriggerDay(todayFrom);
84
-                            xxlJobLogReport.setRunningCount(0);
85
-                            xxlJobLogReport.setSucCount(0);
86
-                            xxlJobLogReport.setFailCount(0);
82
+                    itemDay.set(Calendar.HOUR_OF_DAY, 23);
83
+                    itemDay.set(Calendar.MINUTE, 59);
84
+                    itemDay.set(Calendar.SECOND, 59);
85
+                    itemDay.set(Calendar.MILLISECOND, 999);
87 86
 
88
-                            Map<String, Object> triggerCountMap = xxlJobLogDao.findLogReport(todayFrom, todayTo);
89
-                            if (triggerCountMap != null && triggerCountMap.size() > 0) {
90
-                                int triggerDayCount = triggerCountMap.containsKey("triggerDayCount") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))) : 0;
91
-                                int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))) : 0;
92
-                                int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))) : 0;
93
-                                int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;
87
+                    Date todayTo = itemDay.getTime();
94 88
 
95
-                                xxlJobLogReport.setRunningCount(triggerDayCountRunning);
96
-                                xxlJobLogReport.setSucCount(triggerDayCountSuc);
97
-                                xxlJobLogReport.setFailCount(triggerDayCountFail);
98
-                            }
89
+                    // refresh log-report every minute
90
+                    XxlJobLogReport xxlJobLogReport = new XxlJobLogReport();
91
+                    xxlJobLogReport.setTriggerDay(todayFrom);
92
+                    xxlJobLogReport.setRunningCount(0);
93
+                    xxlJobLogReport.setSucCount(0);
94
+                    xxlJobLogReport.setFailCount(0);
99 95
 
100
-                            // do refresh
101
-                            int ret = xxlJobLogReportDao.update(xxlJobLogReport);
102
-                            if (ret < 1) {
103
-                                xxlJobLogReportDao.save(xxlJobLogReport);
104
-                            }
105
-                        }
96
+                    Map<String, Object> triggerCountMap = xxlJobLogDao.findLogReport(todayFrom, todayTo);
97
+                    if (triggerCountMap != null && triggerCountMap.size() > 0) {
98
+                        int triggerDayCount = triggerCountMap.containsKey("triggerDayCount") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))) : 0;
99
+                        int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))) : 0;
100
+                        int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc") ? Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))) : 0;
101
+                        int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;
106 102
 
107
-                    } catch (Exception e) {
108
-                        if (!toStop) {
109
-                            logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e);
110
-                        }
103
+                        xxlJobLogReport.setRunningCount(triggerDayCountRunning);
104
+                        xxlJobLogReport.setSucCount(triggerDayCountSuc);
105
+                        xxlJobLogReport.setFailCount(triggerDayCountFail);
111 106
                     }
112 107
 
113
-                    // 2、log-clean: switch open & once each day
114
-                    if (xxlJobAdminConfig.getLogRetentionDays() > 0 && System.currentTimeMillis() - lastCleanLogTime > 24 * 60 * 60 * 1000) {
115
-
116
-                        // expire-time
117
-                        Calendar expiredDay = Calendar.getInstance();
118
-                        expiredDay.add(Calendar.DAY_OF_MONTH, -1 * xxlJobAdminConfig.getLogRetentionDays());
119
-                        expiredDay.set(Calendar.HOUR_OF_DAY, 0);
120
-                        expiredDay.set(Calendar.MINUTE, 0);
121
-                        expiredDay.set(Calendar.SECOND, 0);
122
-                        expiredDay.set(Calendar.MILLISECOND, 0);
123
-                        Date clearBeforeTime = expiredDay.getTime();
124
-
125
-                        // clean expired log
126
-                        List<Long> logIds = null;
127
-                        do {
128
-                            logIds = xxlJobLogDao.findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
129
-                            if (logIds != null && logIds.size() > 0) {
130
-                                xxlJobLogDao.clearLog(logIds);
131
-                            }
132
-                        } while (logIds != null && logIds.size() > 0);
133
-
134
-                        // update clean time
135
-                        lastCleanLogTime = System.currentTimeMillis();
108
+                    // do refresh
109
+                    int ret = xxlJobLogReportDao.update(xxlJobLogReport);
110
+                    if (ret < 1) {
111
+                        xxlJobLogReportDao.save(xxlJobLogReport);
136 112
                     }
113
+                }
114
+
115
+            } catch (Exception e) {
116
+                if (!toStop) {
117
+                    logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e.getMessage());
118
+                }
119
+            }
137 120
 
138
-                    try {
139
-                        TimeUnit.MINUTES.sleep(1);
140
-                    } catch (Exception e) {
141
-                        if (!toStop) {
142
-                            logger.error(e.getMessage(), e);
143
-                        }
121
+            // 2、log-clean: switch open & once each day
122
+            if (xxlJobAdminConfig.getLogRetentionDays() > 0 && System.currentTimeMillis() - lastCleanLogTime > 24 * 60 * 60 * 1000) {
123
+
124
+                // expire-time
125
+                Calendar expiredDay = Calendar.getInstance();
126
+                expiredDay.add(Calendar.DAY_OF_MONTH, -1 * xxlJobAdminConfig.getLogRetentionDays());
127
+                expiredDay.set(Calendar.HOUR_OF_DAY, 0);
128
+                expiredDay.set(Calendar.MINUTE, 0);
129
+                expiredDay.set(Calendar.SECOND, 0);
130
+                expiredDay.set(Calendar.MILLISECOND, 0);
131
+                Date clearBeforeTime = expiredDay.getTime();
132
+
133
+                // clean expired log
134
+                List<Long> logIds = null;
135
+                do {
136
+                    logIds = xxlJobLogDao.findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
137
+                    if (logIds != null && logIds.size() > 0) {
138
+                        xxlJobLogDao.clearLog(logIds);
144 139
                     }
140
+                } while (logIds != null && logIds.size() > 0);
141
+
142
+                // update clean time
143
+                lastCleanLogTime = System.currentTimeMillis();
144
+            }
145 145
 
146
+            try {
147
+                TimeUnit.MINUTES.sleep(1);
148
+            } catch (Exception e) {
149
+                if (!toStop) {
150
+                    logger.error(e.getMessage(), e);
146 151
                 }
152
+            }
147 153
 
148
-                logger.info(">>>>>>>>>>> xxl-job, job log report thread stop");
154
+        }
155
+
156
+        logger.info(">>>>>>>>>>> xxl-job, job log report thread stop");
149 157
 
150
-            }
151
-        });
152
-        logrThread.setDaemon(true);
153
-        logrThread.setName("xxl-job, admin JobLogReportHelper");
154
-        logrThread.start();
155 158
     }
156 159
 
157 160
     @PreDestroy

+ 60 - 56
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryMonitorHelper.java Wyświetl plik

@@ -45,73 +45,77 @@ public class JobRegistryMonitorHelper {
45 45
         registryThread = new Thread(new Runnable() {
46 46
             @Override
47 47
             public void run() {
48
-                while (!toStop) {
49
-                    try {
50
-                        // auto registry group
51
-                        List<XxlJobGroup> groupList = xxlJobGroupDao.findByAddressType(0);
52
-                        if (groupList != null && !groupList.isEmpty()) {
53
-
54
-                            // remove dead address (admin/executor)
55
-                            List<Integer> ids = xxlJobRegistryDao.findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
56
-                            if (ids != null && ids.size() > 0) {
57
-                                xxlJobRegistryDao.removeDead(ids);
58
-                            }
48
+                jobRegistryMonitor();
49
+            }
50
+        });
51
+        registryThread.setDaemon(true);
52
+        registryThread.setName("xxl-job, admin JobRegistryMonitorHelper");
53
+        registryThread.start();
54
+    }
55
+
56
+    private void jobRegistryMonitor() {
57
+        while (!toStop) {
58
+            try {
59
+                // auto registry group
60
+                List<XxlJobGroup> groupList = xxlJobGroupDao.findByAddressType(0);
61
+                if (groupList != null && !groupList.isEmpty()) {
62
+
63
+                    // remove dead address (admin/executor)
64
+                    List<Integer> ids = xxlJobRegistryDao.findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
65
+                    if (ids != null && ids.size() > 0) {
66
+                        xxlJobRegistryDao.removeDead(ids);
67
+                    }
59 68
 
60
-                            // fresh online address (admin/executor)
61
-                            HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
62
-                            List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
63
-                            if (list != null) {
64
-                                for (XxlJobRegistry item : list) {
65
-                                    if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
66
-                                        String appName = item.getRegistryKey();
67
-                                        List<String> registryList = appAddressMap.get(appName);
68
-                                        if (registryList == null) {
69
-                                            registryList = new ArrayList<String>();
70
-                                        }
71
-
72
-                                        if (!registryList.contains(item.getRegistryValue())) {
73
-                                            registryList.add(item.getRegistryValue());
74
-                                        }
75
-                                        appAddressMap.put(appName, registryList);
76
-                                    }
69
+                    // fresh online address (admin/executor)
70
+                    HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
71
+                    List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
72
+                    if (list != null) {
73
+                        for (XxlJobRegistry item : list) {
74
+                            if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
75
+                                String appName = item.getRegistryKey();
76
+                                List<String> registryList = appAddressMap.get(appName);
77
+                                if (registryList == null) {
78
+                                    registryList = new ArrayList<String>();
77 79
                                 }
78
-                            }
79 80
 
80
-                            // fresh group address
81
-                            for (XxlJobGroup group : groupList) {
82
-                                List<String> registryList = appAddressMap.get(group.getAppName());
83
-                                String addressListStr = null;
84
-                                if (registryList != null && !registryList.isEmpty()) {
85
-                                    Collections.sort(registryList);
86
-                                    addressListStr = "";
87
-                                    for (String item : registryList) {
88
-                                        addressListStr += item + ",";
89
-                                    }
90
-                                    addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
81
+                                if (!registryList.contains(item.getRegistryValue())) {
82
+                                    registryList.add(item.getRegistryValue());
91 83
                                 }
92
-                                group.setAddressList(addressListStr);
93
-                                xxlJobGroupDao.update(group);
84
+                                appAddressMap.put(appName, registryList);
94 85
                             }
95 86
                         }
96
-                    } catch (Exception e) {
97
-                        if (!toStop) {
98
-                            logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
99
-                        }
100 87
                     }
101
-                    try {
102
-                        TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
103
-                    } catch (InterruptedException e) {
104
-                        if (!toStop) {
105
-                            logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
88
+
89
+                    // fresh group address
90
+                    for (XxlJobGroup group : groupList) {
91
+                        List<String> registryList = appAddressMap.get(group.getAppName());
92
+                        String addressListStr = null;
93
+                        if (registryList != null && !registryList.isEmpty()) {
94
+                            Collections.sort(registryList);
95
+                            addressListStr = "";
96
+                            for (String item : registryList) {
97
+                                addressListStr += item + ",";
98
+                            }
99
+                            addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
106 100
                         }
101
+                        group.setAddressList(addressListStr);
102
+                        xxlJobGroupDao.update(group);
107 103
                     }
108 104
                 }
109
-                logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
105
+            } catch (Exception e) {
106
+                if (!toStop) {
107
+                    logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e.getMessage());
108
+                }
110 109
             }
111
-        });
112
-        registryThread.setDaemon(true);
113
-        registryThread.setName("xxl-job, admin JobRegistryMonitorHelper");
114
-        registryThread.start();
110
+            try {
111
+                TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
112
+            } catch (InterruptedException e) {
113
+                if (!toStop) {
114
+                    logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e.getMessage());
115
+                }
116
+            }
117
+        }
118
+        logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
115 119
     }
116 120
 
117 121
 

+ 180 - 177
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobScheduleHelper.java Wyświetl plik

@@ -59,233 +59,240 @@ public class JobScheduleHelper {
59 59
         scheduleThread = new Thread(new Runnable() {
60 60
             @Override
61 61
             public void run() {
62
+                jobScheduleStop();
63
+            }
64
+        });
65
+        scheduleThread.setDaemon(true);
66
+        scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread");
67
+        scheduleThread.start();
62 68
 
63
-                try {
64
-                    TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis() % 1000);
65
-                } catch (InterruptedException e) {
66
-                    if (!scheduleThreadToStop) {
67
-                        logger.error(e.getMessage(), e);
68
-                    }
69
-                }
70
-                logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
71
-
72
-                // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
73
-                int preReadCount = (xxlJobAdminConfig.getTriggerPoolFastMax() + xxlJobAdminConfig.getTriggerPoolSlowMax()) * 20;
69
+        // ring thread
70
+        ringThread = new Thread(new Runnable() {
71
+            @Override
72
+            public void run() {
73
+                jobScheduleRing();
74
+            }
75
+        });
76
+        ringThread.setDaemon(true);
77
+        ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread");
78
+        ringThread.start();
79
+    }
74 80
 
75
-                while (!scheduleThreadToStop) {
81
+    private void jobScheduleStop() {
76 82
 
77
-                    // Scan Job
78
-                    long start = System.currentTimeMillis();
83
+        try {
84
+            TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis() % 1000);
85
+        } catch (InterruptedException e) {
86
+            if (!scheduleThreadToStop) {
87
+                logger.error(e.getMessage(), e);
88
+            }
89
+        }
90
+        logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
79 91
 
80
-                    Connection conn = null;
81
-                    Boolean connAutoCommit = null;
82
-                    PreparedStatement preparedStatement = null;
92
+        // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
93
+        int preReadCount = (xxlJobAdminConfig.getTriggerPoolFastMax() + xxlJobAdminConfig.getTriggerPoolSlowMax()) * 20;
83 94
 
84
-                    boolean preReadSuc = true;
85
-                    try {
95
+        while (!scheduleThreadToStop) {
86 96
 
87
-                        conn = dataSource.getConnection();
88
-                        connAutoCommit = conn.getAutoCommit();
89
-                        conn.setAutoCommit(false);
97
+            // Scan Job
98
+            long start = System.currentTimeMillis();
90 99
 
91
-                        preparedStatement = conn.prepareStatement("select * from xxl_job_lock where lock_name = 'schedule_lock' for update");
92
-                        preparedStatement.execute();
100
+            Connection conn = null;
101
+            boolean connAutoCommit = true;
102
+            PreparedStatement preparedStatement = null;
93 103
 
94
-                        // tx start
104
+            boolean preReadSuc = true;
105
+            try {
95 106
 
96
-                        // 1、pre read
97
-                        long nowTime = System.currentTimeMillis();
98
-                        List<XxlJobInfo> scheduleList = xxlJobInfoDao.scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
99
-                        if (scheduleList != null && scheduleList.size() > 0) {
100
-                            // 2、push time-ring
101
-                            for (XxlJobInfo jobInfo : scheduleList) {
107
+                conn = dataSource.getConnection();
108
+                connAutoCommit = conn.getAutoCommit();
109
+                conn.setAutoCommit(false);
102 110
 
103
-                                // time-ring jump
104
-                                if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
105
-                                    // 2.1、trigger-expire > 5s:pass && make next-trigger-time
106
-                                    logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
111
+                preparedStatement = conn.prepareStatement("select * from xxl_job_lock where lock_name = 'schedule_lock' for update");
112
+                preparedStatement.execute();
107 113
 
108
-                                    // fresh next
109
-                                    refreshNextValidTime(jobInfo, new Date());
114
+                // tx start
110 115
 
111
-                                } else if (nowTime > jobInfo.getTriggerNextTime()) {
112
-                                    // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
116
+                // 1、pre read
117
+                long nowTime = System.currentTimeMillis();
118
+                List<XxlJobInfo> scheduleList = xxlJobInfoDao.scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
119
+                if (scheduleList != null && scheduleList.size() > 0) {
120
+                    // 2、push time-ring
121
+                    for (XxlJobInfo jobInfo : scheduleList) {
113 122
 
114
-                                    // 1、trigger
115
-                                    jobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);
116
-                                    logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId());
123
+                        // time-ring jump
124
+                        if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
125
+                            // 2.1、trigger-expire > 5s:pass && make next-trigger-time
126
+                            logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
117 127
 
118
-                                    // 2、fresh next
119
-                                    refreshNextValidTime(jobInfo, new Date());
128
+                            // fresh next
129
+                            refreshNextValidTime(jobInfo, new Date());
120 130
 
121
-                                    // next-trigger-time in 5s, pre-read again
122
-                                    if (jobInfo.getTriggerStatus() == 1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {
131
+                        } else if (nowTime > jobInfo.getTriggerNextTime()) {
132
+                            // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
123 133
 
124
-                                        // 1、make ring second
125
-                                        int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
134
+                            // 1、trigger
135
+                            jobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);
136
+                            logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId());
126 137
 
127
-                                        // 2、push time ring
128
-                                        pushTimeRing(ringSecond, jobInfo.getId());
138
+                            // 2、fresh next
139
+                            refreshNextValidTime(jobInfo, new Date());
129 140
 
130
-                                        // 3、fresh next
131
-                                        refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
141
+                            // next-trigger-time in 5s, pre-read again
142
+                            if (jobInfo.getTriggerStatus() == 1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {
132 143
 
133
-                                    }
144
+                                // 1、make ring second
145
+                                int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
134 146
 
135
-                                } else {
136
-                                    // 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time
147
+                                // 2、push time ring
148
+                                pushTimeRing(ringSecond, jobInfo.getId());
137 149
 
138
-                                    // 1、make ring second
139
-                                    int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
150
+                                // 3、fresh next
151
+                                refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
140 152
 
141
-                                    // 2、push time ring
142
-                                    pushTimeRing(ringSecond, jobInfo.getId());
153
+                            }
143 154
 
144
-                                    // 3、fresh next
145
-                                    refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
155
+                        } else {
156
+                            // 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time
146 157
 
147
-                                }
158
+                            // 1、make ring second
159
+                            int ringSecond = (int) ((jobInfo.getTriggerNextTime() / 1000) % 60);
148 160
 
149
-                            }
161
+                            // 2、push time ring
162
+                            pushTimeRing(ringSecond, jobInfo.getId());
150 163
 
151
-                            // 3、update trigger info
152
-                            for (XxlJobInfo jobInfo : scheduleList) {
153
-                                xxlJobInfoDao.scheduleUpdate(jobInfo);
154
-                            }
164
+                            // 3、fresh next
165
+                            refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
155 166
 
156
-                        } else {
157
-                            preReadSuc = false;
158 167
                         }
159 168
 
160
-                        // tx stop
169
+                    }
170
+
171
+                    // 3、update trigger info
172
+                    for (XxlJobInfo jobInfo : scheduleList) {
173
+                        xxlJobInfoDao.scheduleUpdate(jobInfo);
174
+                    }
175
+
176
+                } else {
177
+                    preReadSuc = false;
178
+                }
161 179
 
180
+                // tx stop
181
+
182
+
183
+            } catch (Exception e) {
184
+                if (!scheduleThreadToStop) {
185
+                    logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e.getMessage());
186
+                }
187
+            } finally {
162 188
 
163
-                    } catch (Exception e) {
189
+                // commit
190
+                if (conn != null) {
191
+                    try {
192
+                        conn.commit();
193
+                    } catch (SQLException e) {
164 194
                         if (!scheduleThreadToStop) {
165
-                            logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e);
195
+                            logger.error(e.getMessage(), e);
166 196
                         }
167
-                    } finally {
168
-
169
-                        // commit
170
-                        if (conn != null) {
171
-                            try {
172
-                                conn.commit();
173
-                            } catch (SQLException e) {
174
-                                if (!scheduleThreadToStop) {
175
-                                    logger.error(e.getMessage(), e);
176
-                                }
177
-                            }
178
-                            try {
179
-                                conn.setAutoCommit(connAutoCommit);
180
-                            } catch (SQLException e) {
181
-                                if (!scheduleThreadToStop) {
182
-                                    logger.error(e.getMessage(), e);
183
-                                }
184
-                            }
185
-                            try {
186
-                                conn.close();
187
-                            } catch (SQLException e) {
188
-                                if (!scheduleThreadToStop) {
189
-                                    logger.error(e.getMessage(), e);
190
-                                }
191
-                            }
197
+                    }
198
+                    try {
199
+                        conn.setAutoCommit(connAutoCommit);
200
+                    } catch (SQLException e) {
201
+                        if (!scheduleThreadToStop) {
202
+                            logger.error(e.getMessage(), e);
192 203
                         }
193
-
194
-                        // close PreparedStatement
195
-                        if (null != preparedStatement) {
196
-                            try {
197
-                                preparedStatement.close();
198
-                            } catch (SQLException e) {
199
-                                if (!scheduleThreadToStop) {
200
-                                    logger.error(e.getMessage(), e);
201
-                                }
202
-                            }
204
+                    }
205
+                    try {
206
+                        conn.close();
207
+                    } catch (SQLException e) {
208
+                        if (!scheduleThreadToStop) {
209
+                            logger.error(e.getMessage(), e);
203 210
                         }
204 211
                     }
205
-                    long cost = System.currentTimeMillis() - start;
206
-
212
+                }
207 213
 
208
-                    // Wait seconds, align second
209
-                    if (cost < 1000) {  // scan-overtime, not wait
210
-                        try {
211
-                            // pre-read period: success > scan each second; fail > skip this period;
212
-                            TimeUnit.MILLISECONDS.sleep((preReadSuc ? 1000 : PRE_READ_MS) - System.currentTimeMillis() % 1000);
213
-                        } catch (InterruptedException e) {
214
-                            if (!scheduleThreadToStop) {
215
-                                logger.error(e.getMessage(), e);
216
-                            }
214
+                // close PreparedStatement
215
+                if (null != preparedStatement) {
216
+                    try {
217
+                        preparedStatement.close();
218
+                    } catch (SQLException e) {
219
+                        if (!scheduleThreadToStop) {
220
+                            logger.error(e.getMessage(), e);
217 221
                         }
218 222
                     }
219
-
220 223
                 }
221
-
222
-                logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");
223 224
             }
224
-        });
225
-        scheduleThread.setDaemon(true);
226
-        scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread");
227
-        scheduleThread.start();
225
+            long cost = System.currentTimeMillis() - start;
228 226
 
229 227
 
230
-        // ring thread
231
-        ringThread = new Thread(new Runnable() {
232
-            @Override
233
-            public void run() {
234
-
235
-                // align second
228
+            // Wait seconds, align second
229
+            if (cost < 1000) {  // scan-overtime, not wait
236 230
                 try {
237
-                    TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
231
+                    // pre-read period: success > scan each second; fail > skip this period;
232
+                    TimeUnit.MILLISECONDS.sleep((preReadSuc ? 1000 : PRE_READ_MS) - System.currentTimeMillis() % 1000);
238 233
                 } catch (InterruptedException e) {
239
-                    if (!ringThreadToStop) {
234
+                    if (!scheduleThreadToStop) {
240 235
                         logger.error(e.getMessage(), e);
241 236
                     }
242 237
                 }
238
+            }
243 239
 
244
-                while (!ringThreadToStop) {
240
+        }
245 241
 
246
-                    try {
247
-                        // second data
248
-                        List<Integer> ringItemData = new ArrayList<>();
249
-                        int nowSecond = Calendar.getInstance().get(Calendar.SECOND);   // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
250
-                        for (int i = 0; i < 2; i++) {
251
-                            List<Integer> tmpData = ringData.remove((nowSecond + 60 - i) % 60);
252
-                            if (tmpData != null) {
253
-                                ringItemData.addAll(tmpData);
254
-                            }
255
-                        }
242
+        logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");
243
+    }
256 244
 
257
-                        // ring trigger
258
-                        logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData));
259
-                        if (ringItemData.size() > 0) {
260
-                            // do trigger
261
-                            for (int jobId : ringItemData) {
262
-                                // do trigger
263
-                                jobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
264
-                            }
265
-                            // clear
266
-                            ringItemData.clear();
267
-                        }
268
-                    } catch (Exception e) {
269
-                        if (!ringThreadToStop) {
270
-                            logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e);
271
-                        }
245
+    private void jobScheduleRing() {
246
+
247
+        // align second
248
+        try {
249
+            TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
250
+        } catch (InterruptedException e) {
251
+            if (!ringThreadToStop) {
252
+                logger.error(e.getMessage(), e);
253
+            }
254
+        }
255
+
256
+        while (!ringThreadToStop) {
257
+
258
+            try {
259
+                // second data
260
+                List<Integer> ringItemData = new ArrayList<>();
261
+                int nowSecond = Calendar.getInstance().get(Calendar.SECOND);   // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
262
+                for (int i = 0; i < 2; i++) {
263
+                    List<Integer> tmpData = ringData.remove((nowSecond + 60 - i) % 60);
264
+                    if (tmpData != null) {
265
+                        ringItemData.addAll(tmpData);
272 266
                     }
267
+                }
273 268
 
274
-                    // next second, align second
275
-                    try {
276
-                        TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
277
-                    } catch (InterruptedException e) {
278
-                        if (!ringThreadToStop) {
279
-                            logger.error(e.getMessage(), e);
280
-                        }
269
+                // ring trigger
270
+                logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData));
271
+                if (ringItemData.size() > 0) {
272
+                    // do trigger
273
+                    for (int jobId : ringItemData) {
274
+                        // do trigger
275
+                        jobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
281 276
                     }
277
+                    // clear
278
+                    ringItemData.clear();
279
+                }
280
+            } catch (Exception e) {
281
+                if (!ringThreadToStop) {
282
+                    logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e.getMessage());
282 283
                 }
283
-                logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
284 284
             }
285
-        });
286
-        ringThread.setDaemon(true);
287
-        ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread");
288
-        ringThread.start();
285
+
286
+            // next second, align second
287
+            try {
288
+                TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
289
+            } catch (InterruptedException e) {
290
+                if (!ringThreadToStop) {
291
+                    logger.error(e.getMessage(), e);
292
+                }
293
+            }
294
+        }
295
+        logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
289 296
     }
290 297
 
291 298
     private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws ParseException {
@@ -302,14 +309,10 @@ public class JobScheduleHelper {
302 309
 
303 310
     private void pushTimeRing(int ringSecond, int jobId) {
304 311
         // push async ring
305
-        List<Integer> ringItemData = ringData.get(ringSecond);
306
-        if (ringItemData == null) {
307
-            ringItemData = new ArrayList<Integer>();
308
-            ringData.put(ringSecond, ringItemData);
309
-        }
312
+        List<Integer> ringItemData = ringData.computeIfAbsent(ringSecond, k -> new ArrayList<Integer>());
310 313
         ringItemData.add(jobId);
311 314
 
312
-        logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData));
315
+        logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : {} = {}", ringSecond, ringItemData);
313 316
     }
314 317
 
315 318
     @PreDestroy

+ 6 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobTriggerPoolHelper.java Wyświetl plik

@@ -44,12 +44,13 @@ public class JobTriggerPoolHelper {
44 44
      */
45 45
     @PostConstruct
46 46
     public void start() {
47
+
47 48
         fastTriggerPool = new ThreadPoolExecutor(
48 49
                 10,
49 50
                 xxlJobAdminConfig.getTriggerPoolFastMax(),
50 51
                 60L,
51 52
                 TimeUnit.SECONDS,
52
-                new LinkedBlockingQueue<Runnable>(1000),
53
+                new LinkedBlockingQueue<Runnable>(1024),
53 54
                 new ThreadFactory() {
54 55
                     @Override
55 56
                     public Thread newThread(Runnable r) {
@@ -62,7 +63,7 @@ public class JobTriggerPoolHelper {
62 63
                 xxlJobAdminConfig.getTriggerPoolSlowMax(),
63 64
                 60L,
64 65
                 TimeUnit.SECONDS,
65
-                new LinkedBlockingQueue<Runnable>(2000),
66
+                new LinkedBlockingQueue<Runnable>(2048),
66 67
                 new ThreadFactory() {
67 68
                     @Override
68 69
                     public Thread newThread(Runnable r) {
@@ -113,9 +114,9 @@ public class JobTriggerPoolHelper {
113 114
                 } finally {
114 115
 
115 116
                     // check timeout-count-map
116
-                    long minTim_now = System.currentTimeMillis() / 60000;
117
-                    if (minTim != minTim_now) {
118
-                        minTim = minTim_now;
117
+                    long minTimNow = System.currentTimeMillis() / 60000;
118
+                    if (minTim != minTimNow) {
119
+                        minTim = minTimNow;
119 120
                         jobTimeoutCountMap.clear();
120 121
                     }
121 122
 

+ 0 - 6
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/JacksonUtil.java Wyświetl plik

@@ -1,6 +1,5 @@
1 1
 package com.xxl.job.admin.core.util;
2 2
 
3
-import com.fasterxml.jackson.core.JsonGenerationException;
4 3
 import com.fasterxml.jackson.core.JsonParseException;
5 4
 import com.fasterxml.jackson.databind.JavaType;
6 5
 import com.fasterxml.jackson.databind.JsonMappingException;
@@ -37,10 +36,6 @@ public class JacksonUtil {
37 36
     public static String writeValueAsString(Object obj) {
38 37
         try {
39 38
             return getInstance().writeValueAsString(obj);
40
-        } catch (JsonGenerationException e) {
41
-            logger.error(e.getMessage(), e);
42
-        } catch (JsonMappingException e) {
43
-            logger.error(e.getMessage(), e);
44 39
         } catch (IOException e) {
45 40
             logger.error(e.getMessage(), e);
46 41
         }
@@ -53,7 +48,6 @@ public class JacksonUtil {
53 48
      * @param jsonStr
54 49
      * @param clazz
55 50
      * @return obj
56
-     * @throws Exception
57 51
      */
58 52
     public static <T> T readValue(String jsonStr, Class<T> clazz) {
59 53
         try {

+ 20 - 7
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/AlarmServiceImpl.java Wyświetl plik

@@ -22,6 +22,8 @@ import java.util.Arrays;
22 22
 import java.util.Date;
23 23
 import java.util.HashSet;
24 24
 import java.util.Set;
25
+import java.util.regex.Matcher;
26
+import java.util.regex.Pattern;
25 27
 
26 28
 /**
27 29
  * @author VcKerry on 2020/1/6
@@ -32,6 +34,10 @@ public class AlarmServiceImpl implements AlarmService {
32 34
 
33 35
     private static Logger logger = LoggerFactory.getLogger(AlarmServiceImpl.class);
34 36
 
37
+    /**
38
+     * email check
39
+     */
40
+    private final Pattern emailPattern = Pattern.compile("^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[.][A-Za-z]{2,3}([.][A-Za-z]{2})?$");
35 41
 
36 42
     @Value("${spring.mail.username}")
37 43
     private String emailUserName;
@@ -59,17 +65,24 @@ public class AlarmServiceImpl implements AlarmService {
59 65
 
60 66
         Set<String> alarmAddressSet = new HashSet<String>(Arrays.asList(info.getAlarmEmail().split(",")));
61 67
 
62
-        for (String email : alarmAddressSet) {
68
+        for (String val : alarmAddressSet) {
63 69
             try {
64
-                email = email.trim();
65
-                if (email.startsWith("http://") || email.startsWith("https://")) {
70
+                val = val.trim();
71
+                if (val.startsWith("http://") || val.startsWith("https://")) {
66 72
                     final String content = textContent(group, info, jobLog, personal);
67
-                    alarmResult = failAlarmHttp(email, title, content, jobLog.getId());
68
-                } else if (email.startsWith("sms://")) {
73
+                    alarmResult = failAlarmHttp(val, title, content, jobLog.getId());
74
+                } else if (val.startsWith("sms://")) {
69 75
                     // sms 短信
70 76
                 } else {
71
-                    String content = emailContent(group, info, jobLog);
72
-                    alarmResult = failAlarmEmail(email, title, content, jobLog.getId(), personal);
77
+                    final Matcher matcher = emailPattern.matcher(val);
78
+                    if (matcher.matches()) {
79
+                        // email...
80
+                        String content = emailContent(group, info, jobLog);
81
+                        alarmResult = failAlarmEmail(val, title, content, jobLog.getId(), personal);
82
+                    } else {
83
+                        // other type...
84
+                        logger.info("unknown alarm notify type. title: {}. jobId: {}", title, jobLog.getId());
85
+                    }
73 86
                 }
74 87
             } catch (Exception e) {
75 88
                 alarmResult = false;