See the previous document for the basic environment https://blog.csdn.net/qq_45745830/article/details/121624158?spm=1001.2014.3001.5502https://blog.csdn.net/qq_45745830/article/details/121624158?spm=1001.2014.3001.5502
Introduction to distributed task scheduling
Many times, we need to execute some programs regularly to complete some scheduled operations. If we handle them manually, it will be very troublesome once the amount of tasks is too large, so using scheduled tasks to operate is a very good option.
At present, most applications are distributed or micro services, so we need distributed task scheduling. At present, the popular distributed task scheduling mainly include elastic job, XXL job, quartz, etc. Let's make a comparison here:
featurequartzelastic-jobxxl-jobantaresopencronrely onmysqljdk1.7+, zookeeper 3.4.6+ ,maven3.0.4+mysql ,jdk1.7+ , maven3.0+jdk 1.7+ , redis , zookeeperjdk1.7+ , Tomcat8.0+HAMulti node deployment ensures that only one node performs tasks by competing for database locksThrough the registration and discovery of zookeeper, servers can be added dynamically. Support horizontal expansionCluster deploymentCluster deployment—Task fragmentation—supportsupportsupport—Document perfectionperfectperfectperfectSlightly fewer documentsSlightly fewer documentsManagement interfacenothingsupportsupportsupportsupportDegree of difficultysimplesimplesimplecommonlycommonlycompanyOpenSymphonyDangdang networkpersonalpersonalpersonalAdvanced features—Elastic capacity expansion, multiple operation modes, failure transfer, running state collection, multi-threaded data processing, idempotency, fault-tolerant processing, spring namespace supportElastic capacity expansion, fragment broadcasting, failover, Rolling real-time log, GLUE (support online code editing, no release), task progress monitoring, task dependency, data encryption, email alarm, operation report, internationalizationTask fragmentation, failure transfer, elastic capacity expansion,Time rules support quartz and crontab, kill tasks, on-site execution, and query task running statusUse enterprisePopular products are widely used by companies with low requirements for distributed scheduling36 krypton, Dangdang, Gome, Jinyou, Lenovo, vipshop, AsiaInfo, Ping An, zhubajiePublic comments, full shipment, Youxin used car, auction loan——Static task case
It's easy to use elastic job. Next, let's learn about the use of elastic job. In the case here, we first implement the static task case. The static task case is written in advance, that is, the execution time.
To create a Zookeeper:
docker run -d --name zk \ --net seckill_network --ip 172.36.0.16 \ --restart=always \ -v /etc/localtime:/etc/localtime \ -p 3181:2181 zookeeper:3.4.14
Case realization steps:
1. Import dependent packages 2. Configure the zookeeper node and task name namespace 3. To implement a custom task, you need to implement the SimpleJob interface1) Introducing dependencies in seckill goods
<!-- ElasticJobAutoConfiguration Auto configuration class function--> <dependency> <groupId>com.github.kuhn-he</groupId> <artifactId>elastic-job-lite-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency>
2) Configure elastic job
Configure elastic job in bootstrap.yml as follows:
server: port: 28889 spring: main: #No error reporting allow-circular-references: true allow-bean-definition-overriding: true application: name: job-springboot datasource: #Connect to database driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/elastic_job_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC username: root password: root zkserver: zk-server:3181 #Dynamic Task Usage zknamespace: zknamesp elaticjob: #Static Task Usage zookeeper: server-lists: zk-server:3181 #zookeeper's address namespace: updatetask #Scheduled task namespace
)Task creation
Create com.seckill.goods.task.statictask.StaticJob with the following code:
@Component @ElasticSimpleJob( cron = "1/5 * * * * ?", //Task execution cycle jobName = "updatetask", //Consistent with scheduled task namespace shardingTotalCount = 1 //Slice ) public class StaticJob implements SimpleJob { /** * Business processing method */ @Override public void execute(ShardingContext shardingContext) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); System.out.println("Time:" + simpleDateFormat.format(new Date())); } }
Explanation:
cron: timing expression jobName: This is consistent with the namespace in bootstrap.yml shardingTotalCount: number of slicesDynamic task case
1. Registry configuration
bootstrap.yml add configuration
# Dynamic timed task zkserver: zk-server:3181 zknamespace: zknamesp
2. Create task
Create task class: com.seckill.goods.task.dynamic.DynamicJob
public class DynamicJob implements SimpleJob { //Get the classes we need through spring; private FileService fileService= GetSpringBean.get(FileService.class); /** * Implement corresponding tasks */ @Override public void execute(ShardingContext shardingContext) { fileService.all();//Get database System.out.println(); //Get requested parameters String s = HttpUtil.get("https://www.baidu.com/"); System.out.println(s); String id = shardingContext.getJobParameter(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); String jobName = shardingContext.getJobName(); System.out.println(jobName + "Time:" + simpleDateFormat.format(new Date()) + ":::" + id); } }
@Component public class GetSpringBean implements ApplicationContextAware { //spring class manager // Declare a static variable to hold the spring container context @Autowired private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } public static <T> T get(Class<T> clazz) { return context.getBean(clazz); } }
Listener usage
Write listener: com.seckill.goods.task.dynamic.dynamicplistener
public class DynamicListener extends AbstractDistributeOnceElasticJobListener { /** * Constructor */ public DynamicListener(long startedTimeoutMilliseconds, long completedTimeoutMilliseconds) { super(startedTimeoutMilliseconds, completedTimeoutMilliseconds); } /** * Pre execution notice */ @Override public void doBeforeJobExecutedAtLastStarted(ShardingContexts shardingContexts) { System.out.println("=======doBeforeJobExecutedAtLastStarted======="); } /** * Post execution notification */ @Override public void doAfterJobExecutedAtLastCompleted(ShardingContexts shardingContexts) { System.out.println("=======doAfterJobExecutedAtLastCompleted======="); } }
Create configuration class and configure registry information, com.seckill.goods.task.dynamic.ElasticjobDynamicConfig:
@Configuration public class ElasticjobDynamicConfig { @Value("$") private String zkserver; @Value("$") private String zknamespace; @Autowired private ZookeeperRegistryCenter zookeeperRegistryCenter; @Autowired private DynamicListener dynamicListener; /** * 1.Configure initialization data */ @Bean public ZookeeperConfiguration zkConfig() { //1.Zookeeper address //2. Scheduled task namespace return new ZookeeperConfiguration(zkserver, zknamespace); } /** * 2.Register initialization data */ @Bean(initMethod = "init") public ZookeeperRegistryCenter registryCenter(ZookeeperConfiguration zkConfig) { return new ZookeeperRegistryCenter(zkConfig); } /** * monitor */ @Bean public DynamicListener dynamicListener() { return new DynamicListener(10000L, 100000L); } /** * 3.Dynamically add scheduled task cases */ public void addDynamicTask(String jobName, String cron, int shardingTotalCount, SimpleJob instance, String id) { //1. Add the task operator of elastjob Lite LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder( new SimpleJobConfiguration( JobCoreConfiguration.newBuilder(jobName, cron, shardingTotalCount) .jobParameter(id) //Additional parameters .build(), instance.getClass().getName()) ).overwrite(true).build();//overwrite(true) overwrites the original task with the same name //2. Add the task operator of Lite to the task launcher of Spring and initialize it new SpringJobScheduler(instance, zookeeperRegistryCenter, liteJobConfiguration, dynamicListener).init(); } //cron expression format private static final String cron = "ss mm HH dd MM ? yyyy"; /** * Convert time to Cron expression * "1/5 * * * * ?"; */ public static String date2cron(Date date) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(cron); return simpleDateFormat.format(date); } }
Test class: http://localhost:28889/task?jobName=ytx2&time=5000&id=1 Execute once in five seconds
@RestController @RequestMapping(value = "/task") public class TaskController { @Autowired private ElasticjobDynamicConfig elasticjobDynamicConfig; /** * Dynamic timed task case test */ @GetMapping public String task(String jobName, Long time, String id) { // String cron = "0/" + time + " * * * * ?"; //Delay execution in milliseconds after the current time String cron = ElasticjobDynamicConfig.date2cron(new Date(System.currentTimeMillis() + time)); elasticjobDynamicConfig.addDynamicTask(jobName, cron, 1, new DynamicJob(), id); return "Execution succeeded!"; } }