Se você tivesse uma tarefa que desejava executar apenas uma vez em um cluster de servidores, a intervalos regulares, qual seria a melhor maneira de conseguir isso? A definição de cluster nesse caso é de 2 ou mais servidores idênticos com sessões distribuídas sentadas atrás de um balanceador de carga.
Caso de uso: você tem uma tarefa que é cara de executar e deve ser executada apenas uma vez a cada X horas. Este trabalho pode, por exemplo, repetir vários registros e atualizar seu status.
- O pior cenário é que a execução do trabalho duas vezes invalida seus dados.
- O melhor cenário é que o trabalho utilize recursos em todos os seus servidores.
Resumo dos Requisitos:
- O trabalho ainda deve ser executado, mesmo se um dos nós estiver inativo.
- O trabalho deve ser executado apenas uma vez por agendamento.
- Se vários trabalhos forem agendados ao mesmo tempo ou em sobreposição, o número de trabalhos em execução será distribuído igualmente entre os servidores.
- As máquinas devem ter a mesma base de código e ser sincronizadas via NTP.
- A configuração pode diferir entre nó e nó, por variáveis de ambiente.
- O trabalho deve começar no prazo ou dentro de um determinado intervalo do tempo atribuído. (digamos 5 minutos, por exemplo)
Soluções possíveis
- Defina um nó como nó principal, isso não funciona, pois viola 1 acima.
- Faça uma solicitação para que o balanceador de carga seja equilibrado para iniciar o trabalho. Infelizmente, isso tem o efeito colateral de que, se você tiver vários trabalhos em execução ao mesmo tempo, todos eles possam ser executados na mesma máquina.
Isso teria que ser executado em Java, em um contêiner de servlet. No entanto, não está codificando os trabalhos que estou procurando.
Certamente este é um problema resolvido com a melhor solução conhecida.
Pergunta relacionada. /programming/5949038/schedule-job-executes-twice-on-cluster
Isso não é duplicado, pois a solução é insuficiente conforme os 5 requisitos fornecidos acima. A solução mais votada sofre de um problema de corrida e a segunda solução viola o requisito 3
Vários servidores de aplicativos têm um recurso para "serviços singleton em todo o cluster".
Por exemplo, o Weblogic possui um recurso de Serviço Singleton configurado através do console de administração da web.
Você precisa escrever uma classe que implemente weblogic.cluster.singleton.SingletonService e usá-la para declarar o serviço no console administrativo. O cluster cuida de instanciar a classe e notificá-lo quando o serviço for iniciado ou parado. A interface SingletonService possui um método enable () e deactivate ().
As chamadas da Weblogic são ativadas () quando ele abre o serviço pela primeira vez em um dos nós do cluster. Se o nó selecionado ficar inativo, o servidor administrador "moverá" o serviço em um servidor diferente, chamando de ativar () lá.
http://docs.oracle.com/cd/E12839_01/apirefs.1111/e13952/taskhelp/clusters/ConfigureSingletonService.html
fonte