LTS (light-task-scheduler) é usado principalmente para resolver problemas de agendamento de tarefas distribuídas e oferece suporte a tarefas em tempo real, tarefas agendadas e tarefas Cron. Possui boa escalabilidade, escalabilidade, robustez e estabilidade e é usado por muitas empresas. Também esperamos que os entusiastas do código aberto possam contribuir juntos.
Endereço Github: https://github.com/ltsopensource/light-task-scheduler
endereço oschina: http://git.oschina.net/hugui/light-task-scheduler
Exemplos: https://github.com/ltsopensource/lts-examples
Endereço do documento (em atualização, prevalecerá posteriormente): https://www.gitbook.com/book/qq254963746/lts/details
Ambos os endereços serão atualizados simultaneamente. Se você estiver interessado, junte-se ao grupo QQ: 109500214 (senha do grupo: hello world) para discutir e melhorar juntos. Quanto mais pessoas apoiarem, mais motivação haverá para atualizá-lo. Se quiser, lembre-se de marcar com uma estrela no canto superior direito.
O LTS possui principalmente os seguintes quatro tipos de nós:
Os nós JobClient, JobTracker e TaskTracker são todos无状态
. Vários deles podem ser implantados e excluídos dinamicamente para obter balanceamento de carga e maior capacidade de carga, e a estrutura usa a estratégia FailStore para fazer com que o LTS tenha boa tolerância a falhas.
O centro de registro LTS fornece múltiplas implementações (Zookeeper, redis, etc.). O centro de registro expõe as informações do nó e elege os mestres. (Mongo ou Mysql) armazena filas de tarefas e logs de execução de tarefas, netty ou mina faz a comunicação subjacente e fornece vários métodos de serialização, como fastjson, hessian2, java, etc.
LTS suporta tipos de tarefas:
Suporta modificação dinâmica de parâmetros de tarefas, tempo de execução de tarefas e outras configurações, suporta adição dinâmica de tarefas em segundo plano, suporta suspensão de tarefas Cron, suporta parada manual de execução de tarefas (condicional), suporta estatísticas de monitoramento de tarefas, suporta monitoramento de execução de tarefas de cada nó , Monitoramento JVM, etc.
A figura abaixo é um processo padrão de execução de tarefas em tempo real.
Atualmente, o backend possui uma função de autenticação simples fornecida pelo ztajy. O nome de usuário e a senha estão em auth.cfg e podem ser modificados pelo usuário.
O LTS pode funcionar sem a estrutura Spring, mas considerando que muitos projetos de usuários usam a estrutura Spring, o LTS também fornece suporte para Spring, incluindo Xml e anotações, basta introduzir lts-spring.jar
.
Um registrador de negócios é fornecido no TaskTracker para uso por aplicativos. Por meio desse registrador de negócios, os logs de negócios podem ser enviados ao JobTracker. Esses logs de negócios podem ser concatenados por IDs de tarefas e a execução de tarefas pode ser visualizada em tempo real no LTS. -Programação administrativa.
A expansão SPI pode atingir intrusão zero. Ela só precisa implementar a interface correspondente e pode ser usada pelo LTS. As interfaces de expansão atualmente abertas são.
Quando o TaskTracker que está executando a tarefa fica inativo, o JobTracker alocará imediatamente todas as tarefas atribuídas ao TaskTracker desativado para outros nós normais do TaskTracker para execução.
Monitoramento de recursos, monitoramento de tarefas, etc. podem ser executados nos nós JobTracker e TaskTracker e podem ser visualizados no plano de fundo de gerenciamento LTS-Admin em tempo real para realizar uma alocação razoável de recursos.
A estrutura LTS fornece suporte para quatro resultados de execução, EXECUTE_SUCCESS
, EXECUTE_FAILED
, EXECUTE_LATER
e EXECUTE_EXCEPTION
, e adota mecanismos de processamento correspondentes para cada resultado, como nova tentativa.
O mecanismo FailStore é usado para tolerância a falhas do nó. Fail And Store não afetará a operação do aplicativo atual devido à instabilidade da comunicação remota. Para obter instruções específicas do FailStore, consulte as instruções do FailStore na descrição do conceito.
O projeto é construído principalmente usando maven e atualmente fornece empacotamento de scripts shell. Dependências de ambiente: Java(jdk1.6+)
Maven
O uso do usuário é geralmente dividido em dois tipos:
Você pode fazer upload do pacote jar lts para o warehouse local por meio do comando maven. Adicione o repositório correspondente no pom.xml pai e carregue-o com o comando deploy. Para métodos de citação específicos, consulte os exemplos em lts.
Cada módulo do lts precisa ser empacotado em um pacote jar separado e todos os pacotes de dependência do lts precisam ser importados. Para referência específica sobre quais pacotes jar, você pode consultar os exemplos em lts.
São fornecidos dois scripts de versão (cmd)windows
e (shell)linux
para compilação e implantação:
A execução do script sh build.sh
ou build.cmd
no diretório raiz gerará a pasta lts-{version}-bin
no diretório dist
.
A seguir está sua estrutura de diretórios, na qual o diretório bin contém principalmente os scripts de inicialização do JobTracker e LTS-Admin. jobtracker
contém o arquivo de configuração do JobTracker e o pacote jar que precisa ser usado é o pacote war e o arquivo de configuração relacionado ao lts-admin
-Admin. Estrutura de arquivo de lts-{versão}-bin
-- lts - $ { version }- bin
|-- bin
| |-- jobtracker . cmd
| |-- jobtracker . sh
| |-- lts - admin . cmd
| |-- lts - admin . sh
| |-- lts - monitor . cmd
| |-- lts - monitor . sh
| |-- tasktracker . sh
|-- conf
| |-- log4j . properties
| |-- lts - admin . cfg
| |-- lts - monitor . cfg
| |-- readme . txt
| |-- tasktracker . cfg
| |-- zoo
| |-- jobtracker . cfg
| |-- log4j . properties
| |-- lts - monitor . cfg
|-- lib
| |-- *. jar
|-- war
|-- jetty
| |-- lib
| |-- *. jar
|-- lts - admin . war
conf/zoo
e execute sh jobtracker.sh zoo start
. Se desejar iniciar dois nós JobTracker, será necessário copiar um zoológico, por exemplo, nomeá-lo. zoo2
, modifique o arquivo de configuração em zoo2
e execute sh jobtracker.sh zoo2 start
. O log jobtracker-zoo.out
é gerado na pasta logs.conf/lts-monitor.cfg
e conf/lts-admin.cfg
e, em seguida, execute o script sh lts-admin.sh
ou lts-admin.cmd
em bin
. lts-admin.out
será gerado na pasta logs. Se a inicialização for bem-sucedida, o endereço de acesso será impresso no log. Os pacotes jar que precisam ser importados para o lts incluem lts-jobclient-{version}.jar
, lts-core-{version}.jar
e outros jars dependentes de terceiros.
JobClient jobClient = new RetryJobClient ();
jobClient . setNodeGroup ( "test_jobClient" );
jobClient . setClusterName ( "test_cluster" );
jobClient . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
jobClient . start ();
// 提交任务
Job job = new Job ();
job . setTaskId ( "3213213123" );
job . setParam ( "shopId" , "11111" );
job . setTaskTrackerNodeGroup ( "test_trade_TaskTracker" );
// job.setCronExpression("0 0/1 * * * ?"); // 支持 cronExpression表达式
// job.setTriggerTime(new Date()); // 支持指定时间执行
Response response = jobClient . submitJob ( job );
< bean id = "jobClient" class = "com.github.ltsopensource.spring.JobClientFactoryBean" >
< property name = "clusterName" value = "test_cluster" />
< property name = "registryAddress" value = "zookeeper://127.0.0.1:2181" />
< property name = "nodeGroup" value = "test_jobClient" />
< property name = "masterChangeListeners" >
< list >
< bean class = "com.github.ltsopensource.example.support.MasterChangeListenerImpl" />
</ list >
</ property >
< property name = "jobFinishedHandler" >
< bean class = "com.github.ltsopensource.example.support.JobFinishedHandlerImpl" />
</ property >
< property name = "configs" >
< props >
<!-- 参数 -->
< prop key = "job.fail.store" > leveldb </ prop >
</ props >
</ property >
</ bean >
@ Configuration
public class LTSSpringConfig {
@ Bean ( name = "jobClient" )
public JobClient getJobClient () throws Exception {
JobClientFactoryBean factoryBean = new JobClientFactoryBean ();
factoryBean . setClusterName ( "test_cluster" );
factoryBean . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
factoryBean . setNodeGroup ( "test_jobClient" );
factoryBean . setMasterChangeListeners ( new MasterChangeListener []{
new MasterChangeListenerImpl ()
});
Properties configs = new Properties ();
configs . setProperty ( "job.fail.store" , "leveldb" );
factoryBean . setConfigs ( configs );
factoryBean . afterPropertiesSet ();
return factoryBean . getObject ();
}
}
Os pacotes jar que precisam ser importados para o lts incluem lts-tasktracker-{version}.jar
, lts-core-{version}.jar
e outros jars dependentes de terceiros.
public class MyJobRunner implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
try {
// TODO 业务逻辑
// 会发送到 LTS (JobTracker上)
jobContext . getBizLogger (). info ( "测试,业务日志啊啊啊啊啊" );
} catch ( Exception e ) {
return new Result ( Action . EXECUTE_FAILED , e . getMessage ());
}
return new Result ( Action . EXECUTE_SUCCESS , "执行成功了,哈哈" );
}
}
TaskTracker taskTracker = new TaskTracker ();
taskTracker . setJobRunnerClass ( MyJobRunner . class );
taskTracker . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
taskTracker . setNodeGroup ( "test_trade_TaskTracker" );
taskTracker . setClusterName ( "test_cluster" );
taskTracker . setWorkThreads ( 20 );
taskTracker . start ();
< bean id = "taskTracker" class = "com.github.ltsopensource.spring.TaskTrackerAnnotationFactoryBean" init - method = "start" >
< property name = "jobRunnerClass" value = "com.github.ltsopensource.example.support.MyJobRunner" />
< property name = "bizLoggerLevel" value = "INFO" />
< property name = "clusterName" value = "test_cluster" />
< property name = "registryAddress" value = "zookeeper://127.0.0.1:2181" />
< property name = "nodeGroup" value = "test_trade_TaskTracker" />
< property name = "workThreads" value = "20" />
< property name = "masterChangeListeners" >
< list >
< bean class = "com.github.ltsopensource.example.support.MasterChangeListenerImpl" />
</ list >
</ property >
< property name = "configs" >
< props >
< prop key = "job.fail.store" > leveldb </ prop >
</ props >
</ property >
</ bean >
@ Configuration
public class LTSSpringConfig implements ApplicationContextAware {
private ApplicationContext applicationContext ;
@ Override
public void setApplicationContext ( ApplicationContext applicationContext ) throws BeansException {
this . applicationContext = applicationContext ;
}
@ Bean ( name = "taskTracker" )
public TaskTracker getTaskTracker () throws Exception {
TaskTrackerAnnotationFactoryBean factoryBean = new TaskTrackerAnnotationFactoryBean ();
factoryBean . setApplicationContext ( applicationContext );
factoryBean . setClusterName ( "test_cluster" );
factoryBean . setJobRunnerClass ( MyJobRunner . class );
factoryBean . setNodeGroup ( "test_trade_TaskTracker" );
factoryBean . setBizLoggerLevel ( "INFO" );
factoryBean . setRegistryAddress ( "zookeeper://127.0.0.1:2181" );
factoryBean . setMasterChangeListeners ( new MasterChangeListener []{
new MasterChangeListenerImpl ()
});
factoryBean . setWorkThreads ( 20 );
Properties configs = new Properties ();
configs . setProperty ( "job.fail.store" , "leveldb" );
factoryBean . setConfigs ( configs );
factoryBean . afterPropertiesSet ();
// factoryBean.start();
return factoryBean . getObject ();
}
}
Descrição do parâmetro
Geralmente, apenas uma instância de JobClient é necessária em uma JVM. Não crie uma nova instância de JobClient para cada tarefa. Isso desperdiçará muito recursos, porque um JobClient pode enviar diversas tarefas. A mesma JVM geralmente tenta manter apenas uma instância do TaskTracker. Se houver mais instâncias, isso poderá causar desperdício de recursos. Ao encontrar um TaskTracker que precisa executar várias tarefas, consulte "Um TaskTracker executa várias tarefas" abaixo.
Às vezes, os cenários de negócios exigem a execução de várias tarefas. Algumas pessoas podem perguntar se cada tipo de tarefa requer um TaskTracker para ser executado. Minha resposta é não. Se você estiver em uma JVM, é melhor usar um TaskTracker para executar várias tarefas, porque usar várias instâncias do TaskTracker em uma JVM é um desperdício de recursos (é claro, quando você tem uma grande quantidade de determinadas tarefas). , você pode usar um nó TaskTracker separado para executar esta tarefa). Então, como podemos implementar um TaskTracker para executar múltiplas tarefas? Abaixo está o exemplo de referência que dei.
/**
* 总入口,在 taskTracker.setJobRunnerClass(JobRunnerDispatcher.class)
* JobClient 提交 任务时指定 Job 类型 job.setParam("type", "aType")
*/
public class JobRunnerDispatcher implements JobRunner {
private static final ConcurrentHashMap < String /*type*/ , JobRunner >
JOB_RUNNER_MAP = new ConcurrentHashMap < String , JobRunner >();
static {
JOB_RUNNER_MAP . put ( "aType" , new JobRunnerA ()); // 也可以从Spring中拿
JOB_RUNNER_MAP . put ( "bType" , new JobRunnerB ());
}
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
Job job = jobContext . getJob ();
String type = job . getParam ( "type" );
return JOB_RUNNER_MAP . get ( type ). run ( job );
}
}
class JobRunnerA implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
// TODO A类型Job的逻辑
return null ;
}
}
class JobRunnerB implements JobRunner {
@ Override
public Result run ( JobContext jobContext ) throws Throwable {
// TODO B类型Job的逻辑
return null ;
}
}
Geralmente, ao escrever o TaskTracker, você só precisa testar se a lógica de implementação do JobRunner está correta, mas não deseja iniciar o LTS para testes remotos. Para facilitar os testes, o LTS fornece o método de teste de atalho do JobRunner. Basta integrar com.github.ltsopensource.tasktracker.runner.JobRunnerTester
em sua própria classe de teste e implementar initContext
e newJobRunner
. Como o exemplo em exemplos lts:
public class TestJobRunnerTester extends JobRunnerTester {
public static void main ( String [] args ) throws Throwable {
// Mock Job 数据
Job job = new Job ();
job . setTaskId ( "2313213" );
JobContext jobContext = new JobContext ();
jobContext . setJob ( job );
JobExtInfo jobExtInfo = new JobExtInfo ();
jobExtInfo . setRetry ( false );
jobContext . setJobExtInfo ( jobExtInfo );
// 运行测试
TestJobRunnerTester tester = new TestJobRunnerTester ();
Result result = tester . run ( jobContext );
System . out . println ( JSON . toJSONString ( result ));
}
@ Override
protected void initContext () {
// TODO 初始化Spring容器
}
@ Override
protected JobRunner newJobRunner () {
return new TestJobRunner ();
}
}
Para tarefas Cron do Quartz, você só precisa adicionar algum código à configuração do Spring para conectar-se à plataforma LTS.
< bean class = " com.github.ltsopensource.spring.quartz.QuartzLTSProxyBean " >
< property name = " clusterName " value = " test_cluster " />
< property name = " registryAddress " value = " zookeeper://127.0.0.1:2181 " />
< property name = " nodeGroup " value = " quartz_test_group " />
</ bean >
@ SpringBootApplication
@ EnableJobTracker // 启动JobTracker
@ EnableJobClient // 启动JobClient
@ EnableTaskTracker // 启动TaskTracker
@ EnableMonitor // 启动Monitor
public class Application {
public static void main ( String [] args ) {
SpringApplication . run ( Application . class , args );
}
}
Tudo o que resta é adicionar a configuração correspondente em application.properties. Para obter detalhes, consulte o exemplo no pacote com.github.ltsopensource.examples.springboot
em lts-example.
Quando a máquina possui duas placas de rede na rede interna, às vezes, se o usuário deseja que o tráfego LTS passe pela placa de rede externa, ele precisa alterar o endereço de mapeamento do nome do host para o endereço da placa de rede externa no host. o mesmo vale para a rede interna.
Se o ID do nó for definido quando o nó for iniciado, o LTS definirá um UUID como o ID do nó por padrão. A legibilidade será baixa, mas a exclusividade de cada nó poderá ser garantida se o usuário puder garantir a exclusividade do nó. ID por si mesmo, ele pode setIdentity
para definir, por exemplo, se cada nó for implantado em uma máquina (uma máquina virtual), então a identidade pode ser definida para o nome do host
Suporte a extensões SPI para JobLogger, JobQueue, etc.
Veja a edição nº 389
A experiência de trabalho é superior a três anos
Requisitos de educaçãoBacharelado
Nível de expectativa P6 (engenheiro Java sênior)/P7 (especialista técnico)
Descrição do trabalho
A plataforma de adesão é responsável pelo sistema de usuários do Grupo Alibaba, atende às necessidades dos usuários de várias linhas de negócios dentro do grupo e apoia os usuários e canais de negócios da cooperação externa do grupo. Incluindo login e autorização de usuário, sistema de sessão, registro, gerenciamento de conta, segurança de conta e outras funções em cada extremidade, serviços subjacentes de informações de usuário, gerenciamento de sessão e credenciais, etc., é uma das principais linhas de produtos do grupo, transportando centenas volume de bilhões de chamadas todos os dias, pico de QPS de dezenas de milhões e uma arquitetura de nuvem híbrida distribuída globalmente, etc.
Como Engenheiro de Software, você trabalhará em nossos principais produtos que fornecem funcionalidades críticas para nossa infraestrutura de negócios. Dependendo de seus interesses e experiência, você poderá trabalhar em uma ou mais das seguintes áreas: Globalização, Experiência do usuário, segurança de dados, aprendizado de máquina. , alta disponibilidade do sistema e muito mais.