preface

Xxl-job is a distributed task scheduling platform, whose core design goal is rapid development, simple learning, lightweight, easy to expand, out of the box. Most scheduled tasks in our department are scheduled based on XXL-Jobs, such as report statistics and scheduled data synchronization. Today’s story comes from the day when the product manager wanted to add a manual report data synchronization function in addition to the periodic report data synchronization. Add a manual synchronization button on the report page. When this button is triggered, the report data can be synchronized

Demand analysis

1. Retain the scheduled synchronization function and add manual synchronization

2. The effect of manual data synchronization must be the same as that of scheduled data synchronization

solution

1. Plan 1. Create a manually invoked Controller, and the Controller triggers the data synchronization logic Service

The controller executes the synchronization logic written in the xxl-job executor

2. Plan 2. Create a manually invoked controller and trigger xxL-job executor in the controller

Solution Analysis

In the original timer scenario, in order to avoid that the synchronization logic in the timer is not completed and the timer will trigger the next time leading to inaccurate data synchronization, we did some measures in the actuator to avoid it, such as setting the synchronization completion flag. If based on plan 1, the plan seems to be feasible, but in fact there are potential pit points. That is, when the timer is executed, the manual triggers the execution, or vice versa, when the manual triggers, the timer is also executed. In this case, data synchronization is performed multiple times, resulting in inaccurate data.

After investigating xxL-job, we found that XXL-job provides the function of restful triggering actuator. This function is tailor-made for us. When manually invoked, the actuator is triggered because the invocation logic in the actuator is executed, so it will trigger the means we take to avoid inaccurate data synchronization

How can I manually trigger the XXL-job actuator restful

The detailed introduction can be found on the official website, and the link is as follows

www.xuxueli.com/xxl-job/#6….

The core code block for this example

@RestController
@RequestMapping(value = "xxl-job")
@API (tags = "XXL - Job restful scheduling ")
@Profile("job")
@Slf4j
public class XxlJobController {

    @Autowired
    private XxljobClientHelper xxljobClientHelper;

    @apiOperation (value = "manually triggered task ")
    @GetMapping("/run")
    public AjaxResult execute(a){
        String adminClientAddressUrl = xxljobClientHelper.getAdminClientAddressUrl();
        String accessToken = xxljobClientHelper.getAccessToken();
        log.info("adminClientAddressUrl:{},accessToken:{}", adminClientAddressUrl,accessToken);
        ExecutorBiz executorBiz = new ExecutorBizClient(adminClientAddressUrl, accessToken);
        ReturnT<String> retval = executorBiz.run(getTriggerParam());
        log.info("retval:{}", JSON.toJSONString(retval));
         // 200 indicates normal or other failures
        if(retval.getCode() == 200) {return AjaxResult.success();
        }
        return AjaxResult.error(retval.getMsg(),retval.getCode());
    }

    private TriggerParam getTriggerParam(a){
        TriggerParam triggerParam = new TriggerParam();
        / / task ID
// triggerParam.setJobId(15);
        // Task identifier
        triggerParam.setExecutorHandler("demoJobHandler");
        // Task parameters
        triggerParam.setExecutorParams("Manual trigger task");
        / / task blocking strategy, optional value reference com. The XXL. Job. Core. Enums. ExecutorBlockStrategyEnum
        triggerParam.setExecutorBlockStrategy(ExecutorBlockStrategyEnum.COVER_EARLY.name());
        / / task model, optional value reference com. The XXL. Job. Core. Glue. GlueTypeEnum
        triggerParam.setGlueType(GlueTypeEnum.BEAN.name());
        // GLUE script code
        triggerParam.setGlueSource(null);
        // GLUE script update time, used to determine whether the script has changed and needs to be refreshed
        triggerParam.setGlueUpdatetime(System.currentTimeMillis());
        // ID of this scheduling log
        triggerParam.setLogId(triggerParam.getJobId());
        // Log time of this time
        triggerParam.setLogDateTime(System.currentTimeMillis());
        returntriggerParam; }}Copy the code

Note: The demoJobHandler in this code is the scheduling method in the executor. Form the following

  /** * 1, simple task example (Bean mode) */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        System.out.println("======================param:"+param+"================================ random number:"+new Random().nextInt(1000));
        return ReturnT.SUCCESS;
    }
Copy the code

conclusion

If the first option is chosen, it is not impossible, but also have to do some transformation, such as increasing the global flag bit, and in the setting of the flag bit, but also consider the possible problems in concurrent scenarios. So it’s better to go straight to plan two. The choice of the solution must be based on the business scenario, not based on the business scenario, talking about the technical solution, it is easy to pit

The demo link

Github.com/lyb-geek/sp…