数据库
配置文件
xxl:job:admin:addresses:http://localhost:8080/xxl-job-admin/accessToken:default_tokentimeout:30cookie:XXL_JOB_LOGIN_IDENTITY=executor:appname:springboot3address:ip:port:9989logPath:logretentiondays:10配置xxlJob任务参数
importlombok.Data;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.PropertySource;importorg.springframework.stereotype.Component;@Component@PropertySource("classpath:xxl-job-info.properties")@ConfigurationProperties(prefix="xxl-job-info")@Data@ToStringpublicclassXxlJobInfoVO{privateStringjobGroup;privateStringjobDesc;privateStringauthor;privateStringscheduleType;privateStringglueType;privateStringexecutorHandler;privateStringexecutorRouteStrategy;privateStringmisfireStrategy;privateStringexecutorBlockStrategy;privateStringexecutorTimeout;privateStringexecutorFailRetryCount;privateStringglueRemark;privateStringtriggerStatus;}xxl-job-info.properties
# \u5B9A\u65F6\u5668\u7EC4#这里需要根据自己的执行器改xxl-job-info.jobGroup=5# \u63CF\u8FF0xxl-job-info.jobDesc=\u667A\u6167\u533B\u517B\u5EB7\u8BA2\u5355\u5B9A\u65F6\u53D6\u6D88\u652F\u4ED8# \u521B\u5EFA\u8005xxl-job-info.author=stx# \u5B9A\u65F6\u5668\u7C7B\u578Bxxl-job-info.scheduleType=CRON# glue\u7C7B\u578Bxxl-job-info.glueType=BEAN# \u6267\u884C\u5668\u4EFB\u52A1handlerxxl-job-info.executorHandler=cancelPay# \u6267\u884C\u5668\u8DEF\u7531\u7B56\u7565xxl-job-info.executorRouteStrategy=FIRST# \u8C03\u5EA6\u8FC7\u671F\u7B56\u7565xxl-job-info.misfireStrategy=DO_NOTHING# \u963B\u585E\u5904\u7406\u7B56\u7565xxl-job-info.executorBlockStrategy=SERIAL_EXECUTION# \u4EFB\u52A1\u6267\u884C\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u79D2xxl-job-info.executorTimeout=0# \u5931\u8D25\u91CD\u8BD5\u6B21\u6570xxl-job-info.executorFailRetryCount=0# GLUE\u5907\u6CE8xxl-job-info.glueRemark=GLUE\u4EE3\u7801\u521D\u59CB\u5316# \u8C03\u5EA6\u72B6\u6001\uFF1A0-\u505C\u6B62\uFF0C1-\u8FD0\u884Cxxl-job-info.triggerStatus=1CancelPayUtil
@Component//@RestControllerpublicclassCancelPayUtil{@Value("${xxl.job.cookie}")privateStringcookie;@Value("${xxl.job.admin.addresses}")privateStringxxlJobAdminAddr;@AutowiredprivateXxlJobInfoVOxxlJobInfoVO;//@GetMapping("/removeCancelJob")publicBooleanremoveCancelJob(StringjobId){RestTemplaterestTemplate=newRestTemplate();HttpHeadersheaders=newHttpHeaders();//设置为form方式headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);headers.add("Cookie",cookie);MultiValueMap<String,String>map=newLinkedMultiValueMap<String,String>();map.add("id",jobId);HttpEntity<MultiValueMap<String,String>>requestb=newHttpEntity<MultiValueMap<String,String>>(map,headers);ResponseEntity<String>response=restTemplate.postForEntity(xxlJobAdminAddr+"/jobinfo/remove",requestb,String.class);StringregionString=response.getBody();//获取请求体JSONObjectjsonObject=JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式Stringcode=jsonObject.getString("code");if(!("200".equals(code))){thrownewIllegalArgumentException("xxl-job定时任务删除失败");}returntrue;}//@GetMapping("/uploadCancelJob")publicStringuploadCancelJob(Stringcron,StringorderId){RestTemplaterestTemplate=newRestTemplate();HttpHeadersheaders=newHttpHeaders();//设置为form方式headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);headers.add("Cookie",cookie);MultiValueMap<String,String>map=newLinkedMultiValueMap<String,String>();map.add("jobGroup",xxlJobInfoVO.getJobGroup());map.add("jobDesc",xxlJobInfoVO.getJobDesc());map.add("author",xxlJobInfoVO.getAuthor());map.add("alarmEmail","");map.add("scheduleType",xxlJobInfoVO.getScheduleType());map.add("scheduleConf",cron);map.add("cronGen_display",cron);map.add("schedule_conf_CRON",cron);map.add("schedule_conf_FIX_RATE","");map.add("schedule_conf_FIX_DELAY","");map.add("glueType",xxlJobInfoVO.getGlueType());map.add("executorHandler",xxlJobInfoVO.getExecutorHandler());map.add("executorParam",orderId);map.add("executorRouteStrategy",xxlJobInfoVO.getExecutorRouteStrategy());map.add("childJobId","");map.add("misfireStrategy",xxlJobInfoVO.getMisfireStrategy());map.add("executorBlockStrategy",xxlJobInfoVO.getExecutorBlockStrategy());map.add("executorTimeout",xxlJobInfoVO.getExecutorTimeout());map.add("executorFailRetryCount",xxlJobInfoVO.getExecutorFailRetryCount());map.add("glueRemark",xxlJobInfoVO.getGlueRemark());map.add("glueSource","");map.add("triggerStatus",xxlJobInfoVO.getTriggerStatus());HttpEntity<MultiValueMap<String,String>>requestb=newHttpEntity<MultiValueMap<String,String>>(map,headers);ResponseEntity<String>response=restTemplate.postForEntity(xxlJobAdminAddr+"/jobinfo/add",requestb,String.class);StringregionString=response.getBody();//获取请求体JSONObjectjsonObject=JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式Stringcode=jsonObject.getString("code");StringjobId=jsonObject.getString("content");if(!("200".equals(code))){thrownewIllegalArgumentException("xxl-job定时任务创建失败");}returnjobId;}}DateUtils
publicclassDateUtils{publicstaticStringgetLocalDateTimeToCron(longminutes){LocalDateTimelocalDateTime=LocalDateTime.now();LocalDateTimeplusMinLocalDateTime=localDateTime.plusMinutes(minutes);StringcornExpress=plusMinLocalDateTime.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));returncornExpress;}publicstaticStringgetDateToCron(Longtime){// 示例/* Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.MINUTE, 30); SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy"); String cronExpression = sdf.format(calendar.getTime()); System.out.println("Corn表达式:" + cronExpression); */SimpleDateFormatsdf=newSimpleDateFormat("ss mm HH dd MM ? yyyy");StringcronExpression=sdf.format(time);returncronExpression;}}订单取消逻辑
@Slf4j@ComponentpublicclassOrderTimeOutJob{@ResourceprivateIOrderInfoServiceorderInfoService;@XxlJob("cancelPay")publicvoidjob(){log.info(">>>>>>>>进入xxl-job定时任务执行方法");StringorderNumber=XxlJobHelper.getJobParam();orderInfoService.update(Wrappers.<OrderInfo>lambdaUpdate().eq(OrderInfo::getOrderNumber,orderNumber).set(OrderInfo::getPayStatus,5));}}定时任务创建逻辑
@RestController@RequestMapping("/orderInfo")@Slf4jpublicclassOrderInfoController{@ResourceprivateIOrderInfoServiceorderInfoService;@ResourceprivateCancelPayUtilcancelPayUtil;@ResourceprivateIOrderJobServiceorderJobService;@PostMapping("/saveOrderInfo")@Transactional(rollbackFor=Exception.class)publicBooleansaveOrderInfo(StringorderNumber){OrderInfoorderInfo=newOrderInfo();orderInfo.setOrderNumber(orderNumber);booleansaveResultBoolean=orderInfoService.save(orderInfo);StringlocalDateTimeToCron=DateUtils.getLocalDateTimeToCron(2);StringjobId=cancelPayUtil.uploadCancelJob(localDateTimeToCron,orderNumber);BooleanjobIsExist=jobId.isEmpty()||jobId.equals("")?false:true;if(jobIsExist){OrderJoborderJob=newOrderJob();orderJob.setOrderNumber(orderNumber);orderJob.setJobId(jobId);orderJobService.save(orderJob);}log.info(String.format("订单号: %s,订单取消时间: %s",orderNumber,localDateTimeToCron));returnsaveResultBoolean&&jobIsExist;}}定时任务取消逻辑
@RestController@RequestMapping("/payInfo")@Slf4jpublicclassPayController{@ResourceprivateCancelPayUtilcancelPayUtil;@ResourceprivateIOrderJobServiceorderJobService;@RequestMapping("/payInfo")publicBooleanpayInfo(StringorderNumber){//业务逻辑...//支付成功,取消定时任务LambdaQueryWrapper<OrderJob>jobLambdaQueryWrapper=newLambdaQueryWrapper<OrderJob>().eq(OrderJob::getOrderNumber,orderNumber);OrderJoborderJob=orderJobService.getOne(jobLambdaQueryWrapper);returncancelPayUtil.removeCancelJob(orderJob.getJobId());}}