数据库


配置文件
yaml
xxl:
job:
admin:
addresses: http://localhost:8080/xxl-job-admin/
accessToken: default_token
timeout: 30
cookie: XXL_JOB_LOGIN_IDENTITY=
executor:
appname: springboot3
address:
ip:
port: 9989
logPath:
logretentiondays: 10
配置xxlJob任务参数
java
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:xxl-job-info.properties")
@ConfigurationProperties(prefix = "xxl-job-info")
@Data
@ToString
public class XxlJobInfoVO {
private String jobGroup;
private String jobDesc;
private String author;
private String scheduleType;
private String glueType;
private String executorHandler;
private String executorRouteStrategy;
private String misfireStrategy;
private String executorBlockStrategy;
private String executorTimeout;
private String executorFailRetryCount;
private String glueRemark;
private String triggerStatus;
}
xxl-job-info.properties
yaml
# \u5B9A\u65F6\u5668\u7EC4
#这里需要根据自己的执行器改
xxl-job-info.jobGroup=5
# \u63CF\u8FF0
xxl-job-info.jobDesc=\u667A\u6167\u533B\u517B\u5EB7\u8BA2\u5355\u5B9A\u65F6\u53D6\u6D88\u652F\u4ED8
# \u521B\u5EFA\u8005
xxl-job-info.author=stx
# \u5B9A\u65F6\u5668\u7C7B\u578B
xxl-job-info.scheduleType=CRON
# glue\u7C7B\u578B
xxl-job-info.glueType=BEAN
# \u6267\u884C\u5668\u4EFB\u52A1handler
xxl-job-info.executorHandler=cancelPay
# \u6267\u884C\u5668\u8DEF\u7531\u7B56\u7565
xxl-job-info.executorRouteStrategy=FIRST
# \u8C03\u5EA6\u8FC7\u671F\u7B56\u7565
xxl-job-info.misfireStrategy=DO_NOTHING
# \u963B\u585E\u5904\u7406\u7B56\u7565
xxl-job-info.executorBlockStrategy=SERIAL_EXECUTION
# \u4EFB\u52A1\u6267\u884C\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u79D2
xxl-job-info.executorTimeout=0
# \u5931\u8D25\u91CD\u8BD5\u6B21\u6570
xxl-job-info.executorFailRetryCount=0
# GLUE\u5907\u6CE8
xxl-job-info.glueRemark=GLUE\u4EE3\u7801\u521D\u59CB\u5316
# \u8C03\u5EA6\u72B6\u6001\uFF1A0-\u505C\u6B62\uFF0C1-\u8FD0\u884C
xxl-job-info.triggerStatus=1
CancelPayUtil
java
@Component
//@RestController
public class CancelPayUtil {
@Value("${xxl.job.cookie}")
private String cookie;
@Value("${xxl.job.admin.addresses}")
private String xxlJobAdminAddr;
@Autowired
private XxlJobInfoVO xxlJobInfoVO;
//@GetMapping("/removeCancelJob")
public Boolean removeCancelJob(String jobId) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//设置为form方式
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("Cookie", cookie);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id",jobId);
HttpEntity<MultiValueMap<String, String>> requestb = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity(xxlJobAdminAddr + "/jobinfo/remove", requestb, String.class);
String regionString = response.getBody();//获取请求体
JSONObject jsonObject = JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式
String code = jsonObject.getString("code");
if (!("200".equals(code))) {
throw new IllegalArgumentException("xxl-job定时任务删除失败");
}
return true;
}
//@GetMapping("/uploadCancelJob")
public String uploadCancelJob(String cron, String orderId) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//设置为form方式
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("Cookie", cookie);
MultiValueMap<String, String> map = new LinkedMultiValueMap<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 = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity(xxlJobAdminAddr + "/jobinfo/add", requestb, String.class);
String regionString = response.getBody();//获取请求体
JSONObject jsonObject = JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式
String code = jsonObject.getString("code");
String jobId = jsonObject.getString("content");
if (!("200".equals(code))) {
throw new IllegalArgumentException("xxl-job定时任务创建失败");
}
return jobId;
}
}
DateUtils
java
public class DateUtils {
public static String getLocalDateTimeToCron(long minutes){
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime plusMinLocalDateTime = localDateTime.plusMinutes(minutes);
String cornExpress = plusMinLocalDateTime.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));
return cornExpress;
}
public static String getDateToCron(Long time){
// 示例
/*
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);
*/
SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
String cronExpression = sdf.format(time);
return cronExpression;
}
}
订单取消逻辑
java
@Slf4j
@Component
public class OrderTimeOutJob {
@Resource
private IOrderInfoService orderInfoService;
@XxlJob("cancelPay")
public void job() {
log.info(">>>>>>>>进入xxl-job定时任务执行方法");
String orderNumber = XxlJobHelper.getJobParam();
orderInfoService.update(
Wrappers.<OrderInfo>lambdaUpdate()
.eq(OrderInfo::getOrderNumber, orderNumber)
.set(OrderInfo::getPayStatus,5)
);
}
}
定时任务创建逻辑
java
@RestController
@RequestMapping("/orderInfo")
@Slf4j
public class OrderInfoController {
@Resource
private IOrderInfoService orderInfoService;
@Resource
private CancelPayUtil cancelPayUtil;
@Resource
private IOrderJobService orderJobService;
@PostMapping("/saveOrderInfo")
@Transactional(rollbackFor = Exception.class)
public Boolean saveOrderInfo(String orderNumber) {
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderNumber(orderNumber);
boolean saveResultBoolean = orderInfoService.save(orderInfo);
String localDateTimeToCron = DateUtils.getLocalDateTimeToCron(2);
String jobId = cancelPayUtil.uploadCancelJob(localDateTimeToCron, orderNumber);
Boolean jobIsExist = jobId.isEmpty() || jobId.equals("") ? false : true;
if (jobIsExist){
OrderJob orderJob = new OrderJob();
orderJob.setOrderNumber(orderNumber);
orderJob.setJobId(jobId);
orderJobService.save(orderJob);
}
log.info(String.format("订单号: %s,订单取消时间: %s",orderNumber,localDateTimeToCron));
return saveResultBoolean && jobIsExist;
}
}
定时任务取消逻辑
java
@RestController
@RequestMapping("/payInfo")
@Slf4j
public class PayController {
@Resource
private CancelPayUtil cancelPayUtil;
@Resource
private IOrderJobService orderJobService;
@RequestMapping("/payInfo")
public Boolean payInfo(String orderNumber) {
//业务逻辑...
//支付成功,取消定时任务
LambdaQueryWrapper<OrderJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<OrderJob>().eq(OrderJob::getOrderNumber, orderNumber);
OrderJob orderJob = orderJobService.getOne(jobLambdaQueryWrapper);
return cancelPayUtil.removeCancelJob(orderJob.getJobId());
}
}