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", "xxx@satcloud.com.cn"); // 執行器路由策略 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; } }
到此,對外新增、編輯、刪除、啟動、掛起等接口就已經寫好了。