prefácio
O componente de tarefa de temporização é frequentemente usado no processo de trabalho. Em um nó independente, você pode escolher diretamente usar o próprio componente de tarefa de temporização hubble-task do Spring . Depois que essa tarefa de temporização for confirmada e solidificada com uma estratégia de gatilho de tempo, ele não pode ser ligado e desligado dinamicamente, então houve o Quartz mais tarde .
Quartz é um projeto de código aberto na área de tarefas cronometradas, desenvolvido em JAVA , que pode agendar o início, a parada e a estratégia de tarefas cronometradas por meio de API e possui funções poderosas, como suporte para transações JTA e clusters.
Mas o Quartzo tem algumas de suas desvantagens:
- O Quartz ajusta o tempo das tarefas e precisa ser agendado por meio da API , que não está separada do sistema de negócios em essência.
- O Quartz precisa persistir os dados na tabela de dados subjacente e a intrusão de dados no sistema de negócios é relativamente alta.
- Quartz também não suporta execução de agendamento distribuído, apenas uma única tarefa pode ser executada individualmente
O elastic -job é o segundo pacote do Dangdang baseado no Quartz.Existem duas versões do elastic-job :
- Elastic-Job-Cloud : Método de implantação para microsserviços
- Elastic-Job-Lite : implantação baseada no zookeeper como centro de registro
Essas duas versões são iguais na API , exceto pelos diferentes métodos de implantação . Elastic-job adicionou muitos recursos novos em comparação ao Quartz :
- Página de interface do usuário de suporte, você pode ajustar dinamicamente a estratégia de tempo e iniciar e parar na página da web
- Baseado no Zookeeper como agendamento distribuído, o agendamento é dissociado das tarefas
- Suporta fragmentação de agendamento distribuído, a mesma tarefa pode ser dividida em várias partes para execução
- Vários tipos de trabalho, com suporte a fluxo de dados Simple, DataFlow e scripts Script
- Failover, as tarefas das máquinas offline serão fragmentadas novamente para execução
- A consistência da fragmentação do trabalho, as tarefas não serão repetidas após a fragmentação
- Compensação de trabalho por execuções perdidas
Instalar
Para instalar o elastic-job-lite , você precisa instalar o zookeeper com antecedência . Se precisar de um tutorial de instalação, você pode ler este artigo: Instale o Zookeeper Online no Linux
O endereço do elastic-job no apache: elasticjob
Em seguida, você precisa executar o arquivo jar contendo Elastic-Job-Lite e código comercial. Não se limitando aos métodos de inicialização jar ou war.
Endereço de origem: elastic-job-lite
iniciar console elástico-job-lite
Baixe o código fonte da versão 2.1.4:
https://codeload.github.com/apache/shardingsphere-elasticjob/zip/refs/tags/2.1.4
Após o download ser concluído e descompactado, existem os seguintes diretórios:
Insira o console elastic-job-lite no arquivo elastic-job-lite . Pacote neste diretório, comando package
mvn clean install -Dmaven.test.skip=true
Após o empacotamento, inicie o pacote jar ou inicie o código-fonte diretamente, encontre a classe ConsoleBootstrap no módulo do console para iniciar
Após a conclusão da inicialização, visite ip:8899 e a senha da conta é: root/root
Após entrar no sistema, entre na configuração da central de cadastro, preencha o endereço do zookeeper que precisa ser cadastrado para se conectar.
A seguir está a configuração de instalação no Linux . Você também pode colocar diretamente o pacote empacotado no Linux para execução.
instalar console
Após o elastic-job 3.0, não há módulo de console e há um console de interface do usuário mais bonito
Baixe o pacote do console diretamente aqui:
https://archive.apache.org/dist/shardingsphere/elasticjob-ui-3.0.0-RC1/apache-shardingsphere-elasticjob-3.0.0-RC1-lite-ui-bin.tar.gz
Após o download, carregue no servidor para descompactação
tar -zxvf apache-shardingsphere-elasticjob-3.0.0-RC1-lite-ui-bin.tar.gz
Vá para o arquivo bin para começar
./start.sh
Após a inicialização bem-sucedida, acesse o endereço IP: 8088 e a senha da conta padrão é root/root
Após entrar, você precisa adicionar o centro de registro na configuração global - configuração do centro de registro
Após a conclusão da adição, a conexão é estabelecida e o trabalho elástico é inicialmente configurado. Se desejar importar a fonte de dados, você precisa modificar o arquivo de configuração application.properties no arquivo conf
Quero alterá-lo para mysql como banco de dados e preciso adicionar o pacote de conexão ao arquivo lib, que pode ser carregado manualmente.
vim application.properties
Mude para o driver mysql e método de conexão
Salve o arquivo e reinicie elastic-job , adicione uma fonte de dados na configuração da fonte de dados de rastreamento de eventos, conforme mostrado abaixo:
Clique para estabelecer uma conexão, e a configuração e os logs das tarefas agendadas serão registrados na tabela
integrado
fácil integração
Introduzir dependências pom
<dependency>
<groupId>com.cxytiandi</groupId>
<artifactId>elastic-job-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.10.0</version>
</dependency>
Adicione a configuração no arquivo de configuração application.properties:
elasticJob.zk.serverLists=localhost:2181
elasticJob.zk.namespace=user-sync
Então você pode definir diretamente uma classe de trabalho para verificar, o código é o seguinte:
@Component
@ElasticJobConf(name = "TestJob",cron="0 0 0 * * ?",shardingTotalCount=5) // 每天零点执行
public class TestJob extends SimpleJob{
@Override
public void execute(ShardingContext shardingContext) {
// 要执行的逻辑
}
}
A estratégia de temporização deste método depende da anotação ElasticJobConf , basta ajustar a configuração da anotação.
Integração geral
A integração geral tem três classes
- ElasticJobConfig : configuração de componentes de trabalho elástico, por exemplo, centro de configuração zookeeper
- ElasticJobHandler : A classe de execução específica da tarefa de trabalho pode ser configurada aqui
- ElasticJobListener : monitoramento de tarefas de trabalho, início e fim
- ElasticJobProperties : leia a configuração do zookeeper do arquivo de configuração
Introduzir dependências
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-common-core</artifactId>
<version>${elasticjob.version}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>curator-framework</artifactId>
<groupId>org.apache.curator</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>${elasticjob.version}</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>${elasticjob.version}</version>
</dependency>
<!--解决冲突 elasticjob-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.10.0</version>
</dependency>
ElasticJobConfig
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(name = "elasticjob.enabled", havingValue = "true")
public class ElasticJobConfig {
private final ElasticJobProperties jobProperties;
public ElasticJobConfig(ElasticJobProperties jobProperties) {
this.jobProperties = jobProperties;
}
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter() {
return new ZookeeperRegistryCenter(new ZookeeperConfiguration(jobProperties.getServerLists(),
jobProperties.getNamespace()));
}
@Bean
public ElasticJobListener elasticJobListener() {
return new ElasticJobListener(100, 100);
}
}
ElasticJobHandler
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration
@AutoConfigureAfter(com.kyf.pe.trade.dataprocess.assist.config.ElasticJobConfig.class)
@ConditionalOnBean(com.kyf.pe.trade.dataprocess.assist.config.ElasticJobConfig.class)
public class ElasticJobHandlerConfig {
private final ZookeeperRegistryCenter zookeeperRegistryCenter;
public ElasticJobHandlerConfig(ZookeeperRegistryCenter zookeeperRegistryCenter) {
this.zookeeperRegistryCenter = zookeeperRegistryCenter;
}
/**
* 配置任务详细信息
*
* @param jobClass 定时任务实现类
* @param cron 表达式
* @param shardingTotalCount 分片数
* @param shardingItemParameters 分片参数
* @return
*/
private LiteJobConfiguration getLiteJobConfiguration(final Class<? extends SimpleJob> jobClass,
final String cron,
final int shardingTotalCount,
final String shardingItemParameters,
final String jobParameters,
final String description) {
// 定义作业核心配置
JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder(jobClass.getSimpleName(), cron, shardingTotalCount).
shardingItemParameters(shardingItemParameters).jobParameter(jobParameters).description(description).build();
// 定义SIMPLE类型配置
SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(simpleCoreConfig, jobClass.getCanonicalName());
// 定义Lite作业根配置
return LiteJobConfiguration.newBuilder(simpleJobConfig).build();
}
/**
* 具体任务
*/
@Bean(initMethod = "init")
public JobScheduler pushHrhbJobScheduler(final TestJob testjob,
@Value("${job.test.cron}") final String cron,
@Value("${job.test.shardingTotalCount}") final int shardingTotalCount,
@Value("${job.test.description}") final String description) {
return new SpringJobScheduler(testjob, zookeeperRegistryCenter, getLiteJobConfiguration(testjob.getClass(),
cron, shardingTotalCount, "", "", description));
}
}
ElasticJobListener
import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.AbstractDistributeOnceElasticJobListener;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ElasticJobListener extends AbstractDistributeOnceElasticJobListener {
/**
* 设置间隔时间
*
* @param startedTimeoutMilliseconds
* @param completedTimeoutMilliseconds
*/
public ElasticJobListener(long startedTimeoutMilliseconds, long completedTimeoutMilliseconds) {
super(startedTimeoutMilliseconds, completedTimeoutMilliseconds);
}
@Override
public void doBeforeJobExecutedAtLastStarted(ShardingContexts shardingContexts) {
log.info("任务名:{}开始", shardingContexts.getJobParameter());
}
@Override
public void doAfterJobExecutedAtLastCompleted(ShardingContexts shardingContexts) {
log.info("任务名:{}结束", shardingContexts.getJobParameter());
}
}
Propriedades ElasticJob
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "elasticjob")
public class ElasticJobProperties {
private boolean enabled = true;
private String serverLists;
private String namespace;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getServerLists() {
return serverLists;
}
public void setServerLists(String serverLists) {
this.serverLists = serverLists;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
}