分布式任务调度平台 XXL-JOB(业务代码层动态API调度任务)
一、下载源码
下载2.3.0版本的xxljob https://gitee.com/xuxueli0323/xxl-job/branches
二、导入源码中的sql文件

三、修改admin中的配置文件

管理界面地址: http://localhost:9090/xxl-job-admin 默认账号:admin 默认密码:123456
四、修改源码


MyDynamicApiController
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobQuery;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.util.Date;
import java.util.Map;
@RestController
@RequestMapping("/api/jobinfo")
public class MyDynamicApiController {
private static Logger logger = LoggerFactory.getLogger(MyDynamicApiController.class);
@Autowired
private XxlJobService xxlJobService;
@Autowired
private LoginService loginService;
@RequestMapping(value = "/pageList",method = RequestMethod.POST)
public Map<String, Object> pageList(@RequestBody XxlJobQuery xxlJobQuery) {
return xxlJobService.pageList(
xxlJobQuery.getStart(),
xxlJobQuery.getLength(),
xxlJobQuery.getJobGroup(),
xxlJobQuery.getTriggerStatus(),
xxlJobQuery.getJobDesc(),
xxlJobQuery.getExecutorHandler(),
xxlJobQuery.getAuthor());
}
@PostMapping("/save")
public ReturnT<String> add(@RequestBody(required = true)XxlJobInfo jobInfo) {
// next trigger time (5s后生效,避开预读周期)
long nextTriggerTime = 0;
try {
Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_never_fire"));
}
nextTriggerTime = nextValidTime.getTime();
} catch (ParseException e) {
logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid")+" | "+ e.getMessage());
}
jobInfo.setTriggerStatus(1);
jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(nextTriggerTime);
jobInfo.setUpdateTime(new Date());
if(jobInfo.getId()==0){
return xxlJobService.add(jobInfo);
}else{
return xxlJobService.update(jobInfo);
}
}
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public ReturnT<String> delete(int id) {
return xxlJobService.remove(id);
}
@RequestMapping(value = "/start",method = RequestMethod.GET)
public ReturnT<String> start(int id) {
return xxlJobService.start(id);
}
@RequestMapping(value = "/stop",method = RequestMethod.GET)
public ReturnT<String> stop(int id) {
return xxlJobService.stop(id);
}
@RequestMapping(value="login", method=RequestMethod.GET)
@PermissionLimit(limit=false)
public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){
boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false;
ReturnT<String> result= loginService.login(request, response, userName, password, ifRem);
return result;
}
}
XxlJobQuery
package com.xxl.job.admin.core.model;
public class XxlJobQuery {
private int start;
private int length;
private int triggerStatus;
private String jobDesc;
private String executorHandler;
private String author;
private int jobGroup;
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getTriggerStatus() {
return triggerStatus;
}
public void setTriggerStatus(int triggerStatus) {
this.triggerStatus = triggerStatus;
}
public String getJobDesc() {
return jobDesc;
}
public void setJobDesc(String jobDesc) {
this.jobDesc = jobDesc;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getJobGroup() {
return jobGroup;
}
public void setJobGroup(int jobGroup) {
this.jobGroup = jobGroup;
}
}
五、接入到项目,此例为接入xxl job 的demo上
1、首先是修改配置文件,有两处需要和admin匹配


addresse的端口要和admin匹配,addname也需要匹配
2、pom.xml 引入使用的一些jar
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>

这个是原作者的其实,因为我们本质还是调用了作者xxl job提供的 XxlJobService 里面的方法。
XxlJobInfo
package com.xxl.job.executor.controller;
import java.util.Date;
/**
* xxl-job info
*
* @author xuxueli 2016-1-12 18:25:49
*/
public class XxlJobInfo {
private int id; // 主键ID
private int jobGroup; // 执行器主键ID
private String jobDesc;
private Date addTime;
private Date updateTime;
private String author; // 负责人
private String alarmEmail; // 报警邮件
private String scheduleType; // 调度类型
private String scheduleConf; // 调度配置,值含义取决于调度类型
private String misfireStrategy; // 调度过期策略
private String executorRouteStrategy; // 执行器路由策略
private String executorHandler; // 执行器,任务Handler名称
private String executorParam; // 执行器,任务参数
private String executorBlockStrategy; // 阻塞处理策略
private int executorTimeout; // 任务执行超时时间,单位秒
private int executorFailRetryCount; // 失败重试次数
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
private String glueSource; // GLUE源代码
private String glueRemark; // GLUE备注
private Date glueUpdatetime; // GLUE更新时间
private String childJobId; // 子任务ID,多个逗号分隔
private int triggerStatus; // 调度状态:0-停止,1-运行
private long triggerLastTime; // 上次调度时间
private long triggerNextTime; // 下次调度时间
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getJobGroup() {
return jobGroup;
}
public void setJobGroup(int jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobDesc() {
return jobDesc;
}
public void setJobDesc(String jobDesc) {
this.jobDesc = jobDesc;
}
public Date getAddTime() {
return addTime;
}
public void setAddTime(Date addTime) {
this.addTime = addTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAlarmEmail() {
return alarmEmail;
}
public void setAlarmEmail(String alarmEmail) {
this.alarmEmail = alarmEmail;
}
public String getScheduleType() {
return scheduleType;
}
public void setScheduleType(String scheduleType) {
this.scheduleType = scheduleType;
}
public String getScheduleConf() {
return scheduleConf;
}
public void setScheduleConf(String scheduleConf) {
this.scheduleConf = scheduleConf;
}
public String getMisfireStrategy() {
return misfireStrategy;
}
public void setMisfireStrategy(String misfireStrategy) {
this.misfireStrategy = misfireStrategy;
}
public String getExecutorRouteStrategy() {
return executorRouteStrategy;
}
public void setExecutorRouteStrategy(String executorRouteStrategy) {
this.executorRouteStrategy = executorRouteStrategy;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public String getExecutorBlockStrategy() {
return executorBlockStrategy;
}
public void setExecutorBlockStrategy(String executorBlockStrategy) {
this.executorBlockStrategy = executorBlockStrategy;
}
public int getExecutorTimeout() {
return executorTimeout;
}
public void setExecutorTimeout(int executorTimeout) {
this.executorTimeout = executorTimeout;
}
public int getExecutorFailRetryCount() {
return executorFailRetryCount;
}
public void setExecutorFailRetryCount(int executorFailRetryCount) {
this.executorFailRetryCount = executorFailRetryCount;
}
public String getGlueType() {
return glueType;
}
public void setGlueType(String glueType) {
this.glueType = glueType;
}
public String getGlueSource() {
return glueSource;
}
public void setGlueSource(String glueSource) {
this.glueSource = glueSource;
}
public String getGlueRemark() {
return glueRemark;
}
public void setGlueRemark(String glueRemark) {
this.glueRemark = glueRemark;
}
public Date getGlueUpdatetime() {
return glueUpdatetime;
}
public void setGlueUpdatetime(Date glueUpdatetime) {
this.glueUpdatetime = glueUpdatetime;
}
public String getChildJobId() {
return childJobId;
}
public void setChildJobId(String childJobId) {
this.childJobId = childJobId;
}
public int getTriggerStatus() {
return triggerStatus;
}
public void setTriggerStatus(int triggerStatus) {
this.triggerStatus = triggerStatus;
}
public long getTriggerLastTime() {
return triggerLastTime;
}
public void setTriggerLastTime(long triggerLastTime) {
this.triggerLastTime = triggerLastTime;
}
public long getTriggerNextTime() {
return triggerNextTime;
}
public void setTriggerNextTime(long triggerNextTime) {
this.triggerNextTime = triggerNextTime;
}
}
其中包含将 yyyy-MM-dd HH:mm:ss 格式的 String 类型 字符串转换为 Cron 格式的方法 “dateToCron”
XxlJobUtil
package com.xxl.job.executor.controller;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class XxlJobUtil {
private static String cookie="";
/**
* 将日期字符串转换为 Cron 表达式
* @param dateStr 日期字符串,格式为 "yyyy-MM-dd HH:mm:ss"
* @return 对应的 Cron 表达式,例如 "0 20 11 12 12 ?"
* @throws ParseException 如果日期格式不正确
*/
public static String dateToCron(String dateStr) throws ParseException {
// 定义日期格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
// 解析日期
Date date = dateFormat.parse(dateStr);
// 提取日期和时间的各个部分
SimpleDateFormat secondFormat = new SimpleDateFormat("ss");
SimpleDateFormat minuteFormat = new SimpleDateFormat("mm");
SimpleDateFormat hourFormat = new SimpleDateFormat("HH");
SimpleDateFormat dayFormat = new SimpleDateFormat("dd");
SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
String second = secondFormat.format(date);
String minute = minuteFormat.format(date);
String hour = hourFormat.format(date);
String day = dayFormat.format(date);
String month = monthFormat.format(date);
// 构造 Cron 表达式
return String.format("%s %s %s %s %s ?", second, minute, hour, day, month);
}
/**
* 查询现有的任务(可以关注这个整个调用链,可以自己模仿着写其他的拓展接口)
* @param url
* @param requestInfo
* @return
* @throws HttpException
* @throws IOException
*/
public static JSONObject pageList(String url,JSONObject requestInfo) throws HttpException, IOException {
String path = "/api/jobinfo/pageList";
String targetUrl = url + path;
HttpClient httpClient = new HttpClient();
PostMethod post = new PostMethod(targetUrl);
post.setRequestHeader("cookie", cookie);
RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8");
post.setRequestEntity(requestEntity);
httpClient.executeMethod(post);
JSONObject result = new JSONObject();
result = getJsonObject(post, result);
System.out.println(result.toJSONString());
return result;
}
/**
* 新增/编辑任务
* @param url
* @param requestInfo
* @return
* @throws HttpException
* @throws IOException
*/
public static JSONObject addJob(String url,JSONObject requestInfo) throws HttpException, IOException {
String path = "/api/jobinfo/save";
String targetUrl = url + path;
HttpClient httpClient = new HttpClient();
PostMethod post = new PostMethod(targetUrl);
post.setRequestHeader("cookie", cookie);
RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8");
post.setRequestEntity(requestEntity);
httpClient.executeMethod(post);
JSONObject result = new JSONObject();
result = getJsonObject(post, result);
System.out.println(result.toJSONString());
return result;
}
/**
* 删除任务
* @param url
* @param id
* @return
* @throws HttpException
* @throws IOException
*/
public static JSONObject deleteJob(String url,int id) throws HttpException, IOException {
String path = "/api/jobinfo/delete?id="+id;
return doGet(url,path);
}
/**
* 开始任务
* @param url
* @param id
* @return
* @throws HttpException
* @throws IOException
*/
public static JSONObject startJob(String url,int id) throws HttpException, IOException {
String path = "/api/jobinfo/start?id="+id;
return doGet(url,path);
}
/**
* 停止任务
* @param url
* @param id
* @return
* @throws HttpException
* @throws IOException
*/
public static JSONObject stopJob(String url,int id) throws HttpException, IOException {
String path = "/api/jobinfo/stop?id="+id;
return doGet(url,path);
}
public static JSONObject doGet(String url,String path) throws HttpException, IOException {
String targetUrl = url + path;
HttpClient httpClient = new HttpClient();
HttpMethod get = new GetMethod(targetUrl);
get.setRequestHeader("cookie", cookie);
httpClient.executeMethod(get);
JSONObject result = new JSONObject();
result = getJsonObject(get, result);
return result;
}
private static JSONObject getJsonObject(HttpMethod postMethod, JSONObject result) throws IOException {
if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
InputStream inputStream = postMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();
String str;
while((str = br.readLine()) != null){
stringBuffer.append(str);
}
String response = new String(stringBuffer);
br.close();
return (JSONObject) JSONObject.parse(response);
} else {
return null;
}
}
/**
* 登录
* @param url
* @param userName
* @param password
* @return
* @throws HttpException
* @throws IOException
*/
public static String login(String url, String userName, String password) throws HttpException, IOException {
String path = "/api/jobinfo/login?userName="+userName+"&password="+password;
String targetUrl = url + path;
HttpClient httpClient = new HttpClient();
HttpMethod get = new GetMethod((targetUrl));
httpClient.executeMethod(get);
if (get.getStatusCode() == 200) {
Cookie[] cookies = httpClient.getState().getCookies();
StringBuffer tmpcookies = new StringBuffer();
for (Cookie c : cookies) {
tmpcookies.append(c.toString() + ";");
}
cookie = tmpcookies.toString();
} else {
try {
cookie = "";
} catch (Exception e) {
cookie="";
}
}
return cookie;
}
}
XxlJobController
package com.xxl.job.executor.controller;
import java.util.Date;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
public class XxlJobController {
@Value("${xxl.job.admin.addresses}")
private String url;
@Value("${xxl.username}")
private String username;
@Value("${xxl.password}")
private String password;
@GetMapping("/datetocron")
public String datetocron(@RequestParam("date") String date) throws Exception {
String cron = XxlJobUtil.dateToCron(date);
return cron;
}
@RequestMapping(value = "/pageList",method = RequestMethod.GET)
public Object pageList() throws IOException {
//int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author
JSONObject test=new JSONObject();
test.put("length",10);
XxlJobUtil.login(url,username,password);
JSONObject response = XxlJobUtil.pageList(url, test);
return response.get("data");
}
@RequestMapping(value = "/add",method = RequestMethod.GET)
public void add() throws IOException {
XxlJobInfo xxlJobInfo=new XxlJobInfo();
// xxlJobInfo.setId(0);
xxlJobInfo.setScheduleConf("0/5 * * * * ?");
xxlJobInfo.setJobGroup(1);
xxlJobInfo.setJobDesc("我来试试");
xxlJobInfo.setAddTime(new Date());
xxlJobInfo.setUpdateTime(new Date());
xxlJobInfo.setAuthor("JCccc");
xxlJobInfo.setAlarmEmail("864477182@com");
xxlJobInfo.setScheduleType("CRON");
xxlJobInfo.setScheduleConf("0/5 * * * * ?");
xxlJobInfo.setMisfireStrategy("DO_NOTHING");
xxlJobInfo.setExecutorRouteStrategy("FIRST");
xxlJobInfo.setExecutorHandler("demoJobHandler");
xxlJobInfo.setExecutorParam("att");
xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
xxlJobInfo.setExecutorTimeout(0);
xxlJobInfo.setExecutorFailRetryCount(1);
xxlJobInfo.setGlueType("BEAN");
xxlJobInfo.setGlueSource("");
xxlJobInfo.setGlueRemark("GLUE代码初始化");
xxlJobInfo.setGlueUpdatetime(new Date());
JSONObject test = (JSONObject) JSONObject.toJSON(xxlJobInfo);
XxlJobUtil.login(url,username,password);
JSONObject response = XxlJobUtil.addJob(url, test);
if (response.containsKey("code") && 200 == (Integer) response.get("code")) {
System.out.println("新增成功");
} else {
System.out.println("新增失败");
}
}
@RequestMapping(value = "/stop/{jobId}",method = RequestMethod.GET)
public void stop(@PathVariable("jobId") Integer jobId) throws IOException {
XxlJobUtil.login(url,username,password);
JSONObject response = XxlJobUtil.stopJob(url, jobId);
if (response.containsKey("code") && 200 == (Integer) response.get("code")) {
System.out.println("任务停止成功");
} else {
System.out.println("任务停止失败");
}
}
@RequestMapping(value = "/delete/{jobId}",method = RequestMethod.GET)
public void delete(@PathVariable("jobId") Integer jobId) throws IOException {
XxlJobUtil.login(url,username,password);
JSONObject response = XxlJobUtil.deleteJob(url, jobId);
if (response.containsKey("code") && 200 == (Integer) response.get("code")) {
System.out.println("任务移除成功");
} else {
System.out.println("任务移除失败");
}
}
@RequestMapping(value = "/start/{jobId}",method = RequestMethod.GET)
public void start(@PathVariable("jobId") Integer jobId) throws IOException {
XxlJobUtil.login(url,username,password);
JSONObject response = XxlJobUtil.startJob(url, jobId);
if (response.containsKey("code") && 200 == (Integer) response.get("code")) {
System.out.println("任务启动成功");
} else {
System.out.println("任务启动失败");
}
}
}
注:如果想集成到其他项目,需要将 源码实例 中的 XxlJobConfig 复制过去,并在xml文件中增加配置
XxlJobConfig
package com.xxl.job.executor.core.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
xxl.xml
server:
port: 8084
# log config
logging:
config: classpath:logback-spring.yml
xxl:
username: admin
password: 123456
job:
admin:
addresses: http://127.0.0.1:9090/xxl-job-admin
### 执行器通讯TOKEN 【选填]:非空时启用:
accessToken:
### 执行器AppName 〔选填]:执行器心跳注册分组依据:为空则关闭自动注册
executor:
appname: xxl-job-executor-sample
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
address:
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 9998
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath: /data_nas/webapps/xxljob/log
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
logretentiondays: 30
注2:如果想控制创建任务的id,可以修改以下代码
控制任务id的好处:可以和业务id绑定,进行自由的增删改查
1. admin源码的 save接口的 SQL语句

2. 修改admin源码中我们自己写的add接口

3. 然后调用我们自己写的新增任务接口时设置任务ID

六、开始验证测试
打开admin的HTML页面,这是源码自带的任务:

使用接口测试工具调用add创建一个新任务



调用停止任务接口



那么玩到这,可能大伙会有疑问,我怎么知道哪个我要停止的任务的任务ID是哪个?
所以我抛砖引玉写了个查询列表接口,大家可以意会一下,数据都在的,数据还不好拓展么,什么业务场景,怎么使用怎么调度,都可以自由发挥啊:

剩下还有启动 start接口,删除delete接口,修改update接口,我就不一一展示测试了。
这些增删改查,怎么组合使用,什么业务使用,大家自己玩起来就行。
参考链接:
1、下载源码修改配置信息并进入控制台 教程链接:https://developer.aliyun.com/article/975445
2、接入到自己的项目 教程链接:https://developer.aliyun.com/article/994771
其中需要注意的点。

浙公网安备 33010602011771号