Executando Scheduling em Java com JobRunr
Acredito que todos nós desenvolvedores nos deparamos ou nos depararemos com a necessidade de executarmos alguns processos agendados ou em segundo plano.
Se precisarmos implementar algo deste tipo e a implementação não for feita de forma correta, isso ocasionará em regras complexas e também em problemas de performance.
Existem alternativas para isso, cito por exemplo @Scheduling nativo do SpringBoot, sendo esta uma alternativa simples de usar, porém, mais limitada.
E neste artigo vou demonstrar como também é simples implementar estes recursos com JobRunr com SpringBoot.
JobRunr é uma biblioteca que nos permite executar processos que podem ser agendados e executados em segundo plano em aplicações.
Um dos pontos interessantes dessa biblioteca é que com ela vem embarcado um Dashboard com visão de todos os processos em execução e aqueles que já foram executados. Dessa forma, torna-se mais ágil a análise dos processos executados.
Implementando a biblioteca JobRunr
Como mencionado acima iremos utilizar um projeto Java com SpringBoot, caso você tenha dúvida e nunca tenha criado um projeto com Spring, acesse https://start.spring.io/ e preencha as informações do seu projeto, inclua a dependência [Spring Web] e feito isso baixe o pacote gerado e execute na sua IDE preferida.
Bora começar! Para isso, precisaremos incluir a dependência do JobRunr em nosso projeto. Por isso, inclua ele no pom.xml:
Após incluir a dependência, precisaremos adicionar os atributos de configurações do JobRunr em nosso application.properties:
Uma vez adicionados esses atributos, fica definido que queremos dar início a uma instância do BackgroundJobServer e também ao Dashboard do JobRunr, assim que o Spring iniciar o nosso projeto;
Ao tentarmos subir o projeto após esta configuração, encontraremos um problema:
Por padrão, o JobRunr ao iniciar uma instância do BackgroundJobServer , procura o DataSource configurado no Projeto, mas como não temos nenhum DataSource configurado, teremos os erros da imagem anterior.
Não precisamos nos preocupar quanto a isso, no entanto é aqui que temos que tomar a decisão, se quisermos que as informações dos Processos estejam no banco configurado do nosso projeto ou armazenado no banco in-memory.
Caso escolha a opção de um banco, basta configurar um Spring DataSouce.
Implementando Bean para o StorageProvider
No nosso exemplo, iremos usar o Banco in-memory. Para isso, nós criaremos uma configuração no Spring implementando um Bean para o StorageProvider para quando o JobRunr subir junto com nossa aplicação:
Após a implementação da Configuração, podemos executar nosso projeto e ele agora iniciará subindo o BackgroundJobServer e o Dashboard com sucesso:
Agora, se acessarmos http://localhost:8000, teremos acesso ao Dashboard com as informações dos nossos processos em execução e os que foram executados; ao final veremos algumas imagens com os processos executados.
Implementação dos Endpoints
Agora iremos implementar alguns Endpoints para testarmos a execução de nossos processos.
Antes da criação dos Endpoints para fins de exemplo, vamos criar uma Classe “JobRunrSample.java”. Para executar algo nesta classe temos um método que faz a soma de dois números randômicos e no outro um método que chama este primeiro método, porém antes da chamada tem um Sleep de alguns segundos que passaremos como parâmetro.
Em uma outra classe “ProcessScheduler.java”, vamos implementar 3 opções de chamada do JobRunr:
- Processo que executa somente uma única vez;
- Processo agendado para executar no futuro uma única vez;
- Processo agendado que executa de forma recorrente.
Note que podemos usar a Annotation @Job para identificar o nome do processo no Dashboard, além de poder colocar a quantidade de tentativas de execução em caso de alguma falha.
Finalmente, iremos criar os Endpoints. Criamos a classe “JobRunrSampleApplication.java” para chamar nossos processos.
Neste artigo optei em criar os Endpoints, porém você pode iniciar os processos da maneira que desejar.
Executando os processos
Se executarmos o Endpoint: “http://localhost:8080/api/v1/samples/sleep/20" e na sequência executarmos o Endpoint “http://localhost:8080/api/v1/samples/", notaremos que ele irá finalizar o segundo Endpoint primeiro e depois de passado o tempo determinado na chamada do primeiro Endpoint (neste caso 20seg), ele será finalizado.
Em nosso exemplo, o sleep só está servindo para evidenciarmos a concorrência entre os processos. Caso precise agendar um processo para executar em um tempo determinado, usaremos a chamada do Endpoint “http://localhost:8080/api/v1/samples/scheduledOnce" e caso queira executar de forma recorrente, chamaremos o Endpoint “http://localhost:8080/api/v1/samples/scheduleRecurrently"
Os Endpoint você encontra aqui ( collection do Postman): https://www.postman.com/collections/1cb4c64cea876fbeeb36
Visualizando a execução dos processos
E por fim podemos acompanhar os processos que já foram executados e os que ainda estão em execução.
Conclusão
Com o JobRunr fica fácil controlar seus processos que precisam de agendamento, sem falar que ele ajuda muito na análise dos processos sem a necessidade de você ficar quebrando a cabeça analisando um monte de Logs para saber se seus processos finalizaram ou não. Essas análises nos fazem perder muito tempo em nosso dia a dia, sendo assim espero que essa biblioteca te ajude como tem me ajudado.
A intensão deste artigo era trazer uma introdução sobre a Lib JobRunr. No futuro, podemos explorar como utilizar Schedules em aplicações distribuídas;
O código fonte da implementação você encontrará no meu GitHub: https://github.com/AraujoAlex/jobrunr-sample