xxl-job主要分为调度中心和执行器提供了图像化界面,操作简单上手快,基本实现定时任务自动执行,同时可以针对任务日志进行查看。具体xxl-job可以再github上下载:https://github.com/xuxueli/xxl-job。
本文主要描述xxl-job的接口调用
pom.xml引入
<!--针对自己项目的xxl-job-core进行引入即可--> <dependency> <groupId>com.test</groupId> <artifactId>xxl-job-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--org.apache.commons.httpclient--> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>
application.yml配置信息
xxl: job: admin: # xxl-job admin address list, such as "http://address" or "http://address01,http://address02" # xxl-job-admin 启动地址 addresses: http://192.168.1.59:7000/xxl-job-admin # xxl-job, access token accessToken: executor: # xxl-job executor appname 手动配置的客户端名称 appname: xxl-job-executor-test # xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null address: # xxl-job executor server-info 可以自动分配地址进行注册 ip: port: 9985 # xxl-job executor log-path logpath: logs/applogs/xxl-job/jobhandler # xxl-job executor log-retention-days logretentiondays: 30
controller层代码
package com.controller; import com.alibaba.fastjson.JSONObject; import com.util.TimeUtil; import com.util.results.Resp; import com.hywx.gw.loadservice.util.XxlJobUtil; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.Date; /** * @ClassName: TestSaveXxlController * @Description: * @Author LXYuuuuu * @Date 2020/6/29 15:38 */ @RestController @RequestMapping("/Test") public class TestXxlJobController { private static final Logger LOGGER = LoggerFactory.getLogger(TestXxlJobController.class); @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.executor.appname}") private String executorAppname; @ApiOperation(value = "添加jobInfo并启动", httpMethod = "GET") @GetMapping public Resp saveXxl() { //查询列表数据 try { JSONObject requestInfo = new JSONObject(); // 执行器主键ID requestInfo.put("jobGroup", 2); // 任务执行CRON表达式 long etime1 = System.currentTimeMillis() + 1 * 60 * 1000;//延时函数,单位毫秒,这里是延时了1分钟 String date = TimeUtil.getCron(new Date(etime1)); System.out.println(date); // requestInfo.put("jobCron","0 0/1 * * * ?"); requestInfo.put("jobCron", date); // 任务描述 requestInfo.put("jobDesc", "xxxJob"); // 负责人 requestInfo.put("author", "admin"); // 报警邮件 requestInfo.put("alarmEmail", "[email protected]"); // 执行器路由策略 requestInfo.put("executorRouteStrategy", "FIRST"); // 执行器,任务Handler名称 requestInfo.put("executorHandler", "xxxJobHandler"); // todo 执行器,任务参数 requestInfo.put("executorParam", "测试202006300943"); // 阻塞处理策略 requestInfo.put("executorBlockStrategy", "SERIAL_EXECUTION"); // 任务执行超时时间,单位秒 requestInfo.put("executorTimeout", 0); // 失败重试次数 requestInfo.put("executorFailRetryCount", 1); // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum requestInfo.put("glueType", "BEAN"); // GLUE备注 requestInfo.put("glueRemark", "GLUE代码初始化"); // 调度状态:0-停止,1-运行 requestInfo.put("triggerStatus", 0); // 上次调度时间 requestInfo.put("triggerLastTime", 0); // 下次调度时间 requestInfo.put("triggerNextTime", 0); // requestInfo.put("cronGen_display","0 0/1 * * * ?"); JSONObject response = XxlJobUtil.addJob(adminAddresses, requestInfo); if (response.containsKey("code") && 200 == (Integer) response.get("code")) { //修改任务参数 把id放入 // 执行器主键ID requestInfo.put("executorParam", "JobId=" + response.get("content") + ";测试202006300943"); requestInfo.put("id", Integer.valueOf(response.get("content").toString())); JSONObject responseUpdate = XxlJobUtil.updateJob(adminAddresses, requestInfo); if (responseUpdate.containsKey("code") && 200 == (Integer) responseUpdate.get("code")) { //加入任务成功之后直接启动 JSONObject responseStart = XxlJobUtil.startJob(adminAddresses, Integer.valueOf(response.get("content").toString())); if (responseStart.containsKey("code") && 200 == (Integer) responseStart.get("code")) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-start接口失败!"); } } else { throw new Exception("调用xxl-job-admin-update接口失败!"); } } else { throw new Exception("调用xxl-job-admin-add接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } /** * 删除任务 * * @param id * @return * @throws IOException */ @RequestMapping(value = "/delete", method = RequestMethod.GET) public Resp delete(int id) { try { JSONObject response = XxlJobUtil.deleteJob(adminAddresses, id); if (response.containsKey("code") && 200 == (Integer) response.get("code")) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-delete接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } /** * 开始任务 * * @param id * @return * @throws IOException */ @RequestMapping(value = "/start", method = RequestMethod.GET) public Resp start(int id) { try { JSONObject response = XxlJobUtil.startJob(adminAddresses, id); if (response.containsKey("code") && 200 == (Integer) response.get("code")) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-start接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } /** * 挂起任务 * * @param id * @return * @throws IOException */ @RequestMapping(value = "/stop", method = RequestMethod.GET) public Resp stop(int id) { try { JSONObject response = XxlJobUtil.stopJob(adminAddresses, id); if (response.containsKey("code") && 200 == (Integer) response.get("code")) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-stop接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } /** * 登陆 * * @param userName * @param password * @return * @throws IOException */ @RequestMapping(value = "/login", method = RequestMethod.GET) public Resp login(String userName, String password) { try { String cookie = XxlJobUtil.login(adminAddresses, userName, password); if (StringUtils.isNotBlank(cookie)) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-login接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } /** * 根据xxl-appname获取对应id * * @return * @throws IOException */ @RequestMapping(value = "/getAppNameIdByAppname", method = RequestMethod.GET) public Resp getAppNameIdByAppname() { try { JSONObject response = XxlJobUtil.getAppNameIdByAppname(adminAddresses,executorAppname); if (response.containsKey("code") && 200 == (Integer) response.get("code")) { return Resp.getInstantiationSuccess("成功", null, null); } else { throw new Exception("调用xxl-job-admin-getAppNameIdByAppname接口失败!"); } } catch (Exception e) { return Resp.getInstantiationError("失败" + e.getMessage(), null, null); } } }
XxlJobUtil 工具类
package com.util; import com.alibaba.fastjson.JSONObject; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * @ClassName: ApiUtil * @Description: * @Author LXYuuuuu * @Date 2020/6/30 9:47 */ public class XxlJobUtil { public static Logger logger = LoggerFactory.getLogger(XxlJobUtil.class); private static String cookie=""; /** * 新增/编辑任务 * @param url * @param requestInfo * @return * @throws HttpException * @throws IOException */ public static JSONObject addJob(String url, JSONObject requestInfo) throws HttpException, IOException { String path = "/jobinfo/add"; String targetUrl = url + path; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(targetUrl); RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8"); post.setRequestEntity(requestEntity); httpClient.executeMethod(post); JSONObject result = new JSONObject(); result = getJsonObject(post, result); return result; } public static JSONObject updateJob(String url, JSONObject requestInfo) throws HttpException, IOException { String path = "/jobinfo/update"; String targetUrl = url + path; HttpClient httpClient = new HttpClient(); PostMethod post = new PostMethod(targetUrl); RequestEntity requestEntity = new StringRequestEntity(requestInfo.toString(), "application/json", "utf-8"); post.setRequestEntity(requestEntity); httpClient.executeMethod(post); JSONObject result = new JSONObject(); result = getJsonObject(post, result); return result; } /** * 删除任务 * @param url * @param id * @return * @throws HttpException * @throws IOException */ public static JSONObject deleteJob(String url,int id) throws HttpException, IOException { String path = "/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 = "/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 = "/jobinfo/stop?id="+id; return doGet(url,path); } /** * 根据xxl-appname获取对应id * @param url * @param appnameParam * @return * @throws HttpException * @throws IOException */ public static JSONObject getAppNameIdByAppname(String url,String appnameParam) throws HttpException, IOException { String path = "/jobgroup/getAppNameIdByAppname?appnameParam="+appnameParam; 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 get, JSONObject result) throws IOException { InputStream inputStream = get.getResponseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); StringBuffer stringBuffer = new StringBuffer(); String str = ""; while ((str = br.readLine()) != null) { stringBuffer.append(str); } if (get.getStatusCode() == 200) { /** * 使用此方式会出现 * Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended. * 异常 * String responseBodyAsString = get.getResponseBodyAsString(); * result = JSONObject.parseObject(responseBodyAsString);*/ result = JSONObject.parseObject(stringBuffer.toString()); } else { try { // result = JSONObject.parseObject(get.getResponseBodyAsString()); result = JSONObject.parseObject(stringBuffer.toString()); } catch (Exception e) { result.put("error", stringBuffer.toString()); } } return result; } public static String login(String url, String userName, String password) throws HttpException, IOException { String path = "/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; } }
TimeUtil 工具类
public class TimeUtil { /*** * convert Date to cron ,eg. "0 07 10 15 1 ? 2016" * @param date : 时间点 * @return */ public static String getCron(Date date) { String dateFormat = "ss mm HH dd MM ? yyyy"; return formatDateByPattern(date, dateFormat); } }
Resp返回类
/** * @program: * @description: 前端传递信息封装 * @author: LXYuuuuu * @create: 2020-06-25 09:27 **/ public class Resp { /** 用于状态码 */ public static final int SUCCESS = 200; public static final int ERROR = 404; public static final int TOKENERROR=1001; public static final int DATACOLLISION=1002; /** 数据类型 */ public static final String LIST = "LIST"; public static final String SINGLE = "SINGLE"; public static final String MAP = "MAP"; public static final String PAGE = "PAGE"; public static final String STRING = "STRING"; public static final String JSONSTRING = "JSONSTRING"; /** 操作简单提示 */ public static final String SUCCESS_INFO = "操作成功"; public static final String ERROR_INFO = "操作失败"; /** 状态码 */ private int code; /** 返回提示信息 */ private String message; /** 数据类型 */ private String dataType; /** 返回对象 */ private Object respBody; private Resp() {} /** * @Description: 返回实例化Resp * @return: Resp */ public static Resp getInstantiation() { return new Resp(); } /** * @Description: 返回实例化Resp * @Param: @param code 状态码 * @Param: @param message 返回提示信息 * @Param: @param dataType 数据类型 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiation(int code,String message,String dataType,Object respBody) { Resp resp = getInstantiation(); resp.setCode(code); resp.setMessage(message); resp.setDataType(dataType); resp.setRespBody(respBody); return resp; } /** * * @Description: 返回状态为Success的实例化Resp * @Param: @param message 返回提示信息 * @Param: @param dataType 数据类型 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccess(String message,String dataType,Object respBody) { return getInstantiation(SUCCESS, message, dataType, respBody); } public static Resp getInstantiationTokenError(String message,String dataType,Object respBody) { return getInstantiation(TOKENERROR, message, dataType, respBody); } public static Resp getInstantiationDATACOLLISIONError(String message,String dataType,Object respBody) { return getInstantiation(DATACOLLISION, message, dataType, respBody); } /** * @Description: 返回状态为Success的String类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccessString(String message,Object respBody) { return getInstantiation(SUCCESS, message, STRING, respBody); } /** * * @author: zy * @Description: 返回状态为Success的List类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccessList(String message,Object respBody) { return getInstantiation(SUCCESS, message, LIST, respBody); } /** * @Description: 返回状态为Success的Map类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccessMap(String message,Object respBody) { return getInstantiation(SUCCESS, message, MAP, respBody); } /** * @Description: 返回状态为Success的Page类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccessPage(String message,Object respBody) { return getInstantiation(SUCCESS, message, PAGE, respBody); } /** * @Description: 返回状态为Success的Page类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationSuccessJsonString(String message,Object respBody) { return getInstantiation(SUCCESS, message, JSONSTRING, respBody); } /** * @Description: 返回状态为Error的实例化Resp * @Param: @param message 返回提示信息 * @Param: @param dataType 数据类型 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationError(String message,String dataType,Object respBody) { return getInstantiation(ERROR, message, dataType, respBody); } /** * @Description: 返回状态为Error的String类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationErrorString(String message,Object respBody) { return getInstantiation(ERROR, message, STRING, respBody); } /** * @Description: 返回状态为Error的List类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationErrorList(String message,Object respBody) { return getInstantiation(ERROR, message, LIST, respBody); } /** * @Description: 返回状态为Error的Map类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationErrorMap(String message,Object respBody) { return getInstantiation(ERROR, message, MAP, respBody); } /** * @Description: 返回状态为Error的Page类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationErrorPage(String message,Object respBody) { return getInstantiation(ERROR, message, PAGE, respBody); } /** * @Description: 返回状态为Error的JsonString类型实例化Resp * @Param: @param message 返回提示信息 * @Param: @param respBody 返回对象 * @return: Resp */ public static Resp getInstantiationErrorJsonString(String message,Object respBody) { return getInstantiation(ERROR, message, JSONSTRING, respBody); } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getDataType() { return dataType; } public void setDataType(String dataType) { this.dataType = dataType; } public Object getRespBody() { return respBody; } public void setRespBody(Object respBody) { this.respBody = respBody; } /** * @Description: 判断是否成功 * @return: boolean true:成功,false:错误 */ public boolean isSuccess() { return this.code==SUCCESS; } }
到此,对外新增、编辑、删除、启动、挂起等接口就已经写好了。