[Lilishop Mall] No2-6. Determine the software architecture and build five (this article includes the scheduled task xxl-job)

  Only the backend is involved, see the top column for all directories, codes, documents, and interface paths are:

[Lilishop Mall] Record the study notes of the B2B2C mall system~


 The whole article only introduces the key architectural logic, just look at the source code for specific writing, and it is not complicated to read~

Caution: Some comments in the source code are wrong, some comments have completely opposite meanings, and some comments are not correct. I updated them during the reading process and added new comments where I did not know. So be careful when reading the source code!

Table of contents

A1. Timing task xxl-job

B1. Basic construction of timing task execution module

C1. Test

Remaining content: delayed tasks, etc.


A1. Timing task xxl-job

A brief introduction and use of xxl-job: xxl-job Quick Start Guide - CSDN Blog_Getting Started with xxljob

See this for detailed usage: xxl-job Detailed Usage Guide-CSDN Blog_xxl-job

The focus is on two concepts: scheduling module (scheduling center) and execution module (executor);

The focus of the scheduling module is to manage the scheduling information. It has a visualization platform and can add scheduled tasks to execute. It does not contain business information.

The execution module requires developers to integrate the xxl-job module and develop the actuator business.

B1. Basic construction of timing task execution module

Before we start, let me tell you that the startup of the scheduling module is not introduced here after reading the above article. It could have directly used the jar in the xxl-jod provided by the shop, but it kept reporting an error when starting, and this error cannot be handled, so I downloaded it directly. The corresponding version of the source package is running~

Error: Invalid or corrupt jarfile /Users/hebrf/Desktop/projects/project/lilishop-master/xxl-job/xxl-job-admin-2.3.0-SNAPSHOT.jar

The shop project directly adds timing tasks to the consumer module. We also created a new consumer module in the message middleware in the previous article, and now we can directly add the timetask business in it.

Add dependencies first, because there will be a lot of business logic here later, so you can directly rely on the framework.

/lilishop-master/consumer/pom.xml

    <dependencies>
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>${xxl-job}</version>
        </dependency>
    </dependencies>

Then set the configuration information in the resource configuration file application.xml, set the dispatch center interface and other information

# /lilishop-master/consumer/src/main/resources/application.yml

xxl:
  job:
    admin:
      # 调度中心的部署地址。若调度中心采用集群部署,存在多个地址,则用逗号分隔。执行器将会使用该地址进行”执行器心跳注册”和”任务结果回调”。
      addresses: http://127.0.0.1:9001/xxl-job-admin
    executor:
      # 执行器的应用名称,它是执行器心跳注册的分组依据。
      appname: xxl-job-executor-lilishop
      address:
      # 执行器的IP地址,用于”调度中心请求并触发任务”和”执行器注册”。执行器IP默认为空,表示自动获取IP。多网卡时可手动设置指定IP,手动设置IP时将会绑定Host。
      ip:
      # 执行器的端口号,默认值为9999。单机部署多个执行器时,注意要配置不同的执行器端口。
      port: 8891
      # 日志存放路径
      logpath: ./xxl-job/executor
      # 执行器日志文件的定期清理功能,指定日志保存天数,日志文件过期自动删除。限制至少保存3天,否则功能不生效。
      logretentiondays: 7

Then configure the executor object

//详见: cn.lili.timetask.config.XxlJobConfig

@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appname;

    @Value("${xxl.job.executor.address}")
    private String address;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }

}

After the executor is added, you can add the executed business, that is, the task.

We can see that there are three tasks in the shop, everyMinuteExecute, everyHourExecuteJobHandler, and everyDayExecuteJobHandler, which execute scheduled tasks every minute, every hour, and every day. In the business of the shop project, only these three types of scheduled tasks will be used, so only three types of tasks can be added.

And each task will correspond to multiple small businesses, we cannot directly write the business in the task, the coupling is high and the code is difficult to read. Therefore, an abstract interface for task execution (that is, business) is added to each type of task. When a new business is added, the corresponding interface is implemented and a bean is created, and then the list of abstract interfaces is injected into the task processing class. When the task method is executed, it will Get the business from the list, and execute the business in a for loop~

Then start writing tasks and business

//给每类任务添加了任务执行(就是业务)抽象接口,就拿每分钟举例啦
//详见:cn.lili.timetask.handler.EveryMinuteExecute

public interface EveryMinuteExecute {
    /**
     * 执行
     */
    void execute();
}
//添加任务执行(业务)实现类,我们加上两个实现类来进行测试
//(这里注意,由于我不能在consumer模块中直接加,所以新创建了个consumer-test-xxl-job模块,定时任务都是在这个模块里面测试的,看代码的时候注意啊)
//详见:cn.lili.timetask.handle.impl.TestMinuteExecute1
//详见:cn.lili.timetask.handle.impl.TestMinuteExecute2

@Component
@Slf4j
public class TestMinuteExecute1 implements EveryMinuteExecute {
    @Override
    public void execute() {
        XxlJobHelper.log("TestMinuteExecute1");
        log.info("每分钟子任务执行:TestMinuteExecute1");
    }
}
//添加任务类
//详见:cn.lili.timetask.TimedTaskJobHandler

@Slf4j
@Component
public class TimedTaskJobHandler {

    /**
     * @Description: 将相同任务的业务放到一起执行
     **/
    @Autowired(required = false)
    private List<EveryMinuteExecute> everyMinuteExecutes;

    /**
     * 每分钟任务
     *
     * @throws Exception
     */
    @XxlJob("everyMinuteExecute")
    public ReturnT<String> everyMinuteExecute(String param)  {
        log.info("每分钟任务执行");
        if (everyMinuteExecutes == null || everyMinuteExecutes.size() == 0) {
            return ReturnT.SUCCESS;
        }

        for (int i = 0; i < everyMinuteExecutes.size(); i++) {
            try {
                everyMinuteExecutes.get(i).execute();
            } catch (Exception e) {
                log.error("每分钟任务异常", e);
            }
        }
        return ReturnT.SUCCESS;
    }
}

C1. Test

Before running the consumer module, first open the task scheduling platform and add an executor. At this time, the executor does not have an OnLine machine.

Then start the consumer module, and then you can see that there is an OnLine machine

The task will not be executed at this time, because we haven't added the task yet, let's add the task now, remember to start the task after adding it, and then you can see the task execution

 Timing task added

Remaining content: delayed tasks, etc.

Guess you like

Origin blog.csdn.net/vaevaevae233/article/details/128088535