Analysis of elastic job principle - JobSchedule

Keywords: Programming Spring

Job schedule completes a lot of quartz related content, and also registers the service information to zk, and completes the cache of related job information. In the whole task scheduling, the job schedule completes the elastic job backbone process.

<a name="dI1yS"></a>

JobSchedule

When the elastic job is started, it needs to register the bean schedule, call the init method, and complete the initialization configuration information. The specific operation is as follows

    @Bean(initMethod = "init")
    public JobScheduler simpleJobScheduler(final SimpleJob simpleJob, @Value("${simpleJob.cron}") final String cron, @Value("${simpleJob.shardingTotalCount}") final int shardingTotalCount,
                                           @Value("${simpleJob.shardingItemParameters}") final String shardingItemParameters) {
        return new SpringJobScheduler(simpleJob, regCenter, getLiteJobConfiguration(simpleJob.getClass(), cron, shardingTotalCount, shardingItemParameters), jobEventConfiguration);
    }

The springjobscheduler inherits from the JobScheduler. When the container starts, it calls the init method of the schedule. The processes of the jobSchedule and springjobscheduler are as follows:

As the parent class, jobschedule completes 90% of the schedlue work. Spring JobScheduler only completes the behavior of getting listener, and this behavior is not the parent class definition, only needed in the constructor. It can be considered that the existence of spring JobScheduler is to prepare some config for calling the constructor of JobScheduler. < br / > next remove the job schedule.

public static final String ELASTIC_JOB_DATA_MAP_KEY = "elasticJob";
    
    private static final String JOB_FACADE_DATA_MAP_KEY = "jobFacade";
    
    private final LiteJobConfiguration liteJobConfig;
    
    private final CoordinatorRegistryCenter regCenter;
    
    // TODO is used for testing. The test case can't repeat the new monitor service. In the future, you need to reconstruct the MonitorService into a single case
    @Getter
    private final SchedulerFacade schedulerFacade;
    
    private final JobFacade jobFacade;

Job schedule contains job configuration information, registration center, schedulerface and jobFacade. The registry and configuration center information is from the spring schedule above. Note that the two facades contain a large number of configuration interfaces. < br / > after the init method is called by the registered bean, the job creation in quartz will be completed.

    public void init() {
        LiteJobConfiguration liteJobConfigFromRegCenter = schedulerFacade.updateJobConfiguration(liteJobConfig);
        JobRegistry.getInstance().setCurrentShardingTotalCount(liteJobConfigFromRegCenter.getJobName(), liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getShardingTotalCount());
        JobScheduleController jobScheduleController = new JobScheduleController(
                createScheduler(), createJobDetail(liteJobConfigFromRegCenter.getTypeConfig().getJobClass()), liteJobConfigFromRegCenter.getJobName());
        JobRegistry.getInstance().registerJob(liteJobConfigFromRegCenter.getJobName(), jobScheduleController, regCenter);
        schedulerFacade.registerStartUpInfo(!liteJobConfigFromRegCenter.isDisabled());
        jobScheduleController.scheduleJob(liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getCron());
    }

The job schedule completes the following operations in init: < br / > elastic job integrates the related operations of quartz into the * * job schedule controller * * to start and pause the job

<a name="r1PlF"></a>

Create scheduling

private Scheduler createScheduler() {
        Scheduler result;
        try {
            StdSchedulerFactory factory = new StdSchedulerFactory();
            factory.initialize(getBaseQuartzProperties());
            result = factory.getScheduler();
            result.getListenerManager().addTriggerListener(schedulerFacade.newJobTriggerListener());
        } catch (final SchedulerException ex) {
            throw new JobSystemException(ex);
        }
        return result;
    }

Creating SchedulerFactory in quartz <a name="qtzK3"></a>

Create jobs

private JobDetail createJobDetail(final String jobClass) {
        JobDetail result = JobBuilder.newJob(LiteJob.class).withIdentity(liteJobConfig.getJobName()).build();
        result.getJobDataMap().put(JOB_FACADE_DATA_MAP_KEY, jobFacade);
        Optional<ElasticJob> elasticJobInstance = createElasticJobInstance();
        if (elasticJobInstance.isPresent()) {
            result.getJobDataMap().put(ELASTIC_JOB_DATA_MAP_KEY, elasticJobInstance.get());
        } else if (!jobClass.equals(ScriptJob.class.getCanonicalName())) {
            try {
                result.getJobDataMap().put(ELASTIC_JOB_DATA_MAP_KEY, Class.forName(jobClass).newInstance());
            } catch (final ReflectiveOperationException ex) {
                throw new JobConfigurationException("Elastic-Job: Job class '%s' can not initialize.", jobClass);
            }
        }
        return result;
    }

<a name="GMHN8"></a>

job scheduling

public void scheduleJob(final String cron) {
        try {
            if (!scheduler.checkExists(jobDetail.getKey())) {
                scheduler.scheduleJob(jobDetail, createTrigger(cron));
            }
            scheduler.start();
        } catch (final SchedulerException ex) {
            throw new JobSystemException(ex);
        }
    }

jobSchedule invoked the scheduleJob of the * job scheduling controller [JobScheduleController] in init. **Here elsatic job completes the job scheduling <a name="0T0bG"></a>

Job registration

elastic job will register job related information to zk before starting scheduling

JobRegistry.getInstance().registerJob(liteJobConfigFromRegCenter.getJobName(), jobScheduleController, regCenter);

_The job registry registers the path on zk, caches the jobScheduleController and regCenter in the map, and then extracts the relevant information from the map when the task changes

public void registerJob(final String jobName, final JobScheduleController jobScheduleController, final CoordinatorRegistryCenter regCenter) {
        schedulerMap.put(jobName, jobScheduleController);
        regCenterMap.put(jobName, regCenter);
        regCenter.addCacheData("/" + jobName);
    }

<a name="K8g4E"></a>

Registration start information

This is done by the scheduler facade. There are quite a lot of things in it. Later on

Posted by EchoFool on Fri, 03 Jan 2020 09:56:55 -0800