Para o bem ou para o mal, migramos todo o nosso aplicativo da web LAMP de máquinas dedicadas para a nuvem (máquinas Amazon EC2). Está indo muito bem até agora, mas a forma como fazemos crons está abaixo do ideal. Tenho uma pergunta específica da Amazon sobre como gerenciar melhor os cron jobs na nuvem usando "o jeito da Amazon".
O problema : temos vários servidores da web e precisamos executar crons para jobs em lote, como criar feeds RSS, disparar e-mails, muitas coisas diferentes, na verdade. MAS os cron jobs precisam ser executados apenas em uma máquina porque eles geralmente gravam no banco de dados e, portanto, duplicariam os resultados se executados em várias máquinas.
Até agora, designamos um dos servidores web como o "servidor web mestre" e ele tem algumas tarefas "especiais" que os outros servidores web não têm. A desvantagem da computação em nuvem é a confiabilidade - não queremos um "servidor web mestre" porque é um ponto único de falha. Queremos que todos sejam idênticos e sejam capazes de aumentar e diminuir a escala sem nos lembrar de não retirar o servidor da web mestre do cluster.
Como podemos redesenhar nosso aplicativo para converter tarefas cron do Linux em itens de trabalho transitórios que não têm um único ponto de falha?
Minhas ideias até agora:
- Tenha uma máquina dedicada apenas ao funcionamento de crons. Isso seria um pouco mais gerenciável, mas ainda seria um ponto único de falha e desperdiçaria algum dinheiro tendo uma instância extra.
- Alguns trabalhos podem ser movidos de crons do Linux para eventos do MySQL, no entanto, não sou um grande fã dessa ideia, pois não quero colocar a lógica do aplicativo na camada do banco de dados.
- Talvez possamos executar todos os crons em todas as máquinas, mas mudar nossos scripts cron para que todos eles comecem com um pouco de lógica que implementa um mecanismo de bloqueio de forma que apenas um servidor realmente execute uma ação e os outros simplesmente pulem. Não sou fã dessa ideia, pois parece potencialmente problemática e eu preferiria usar uma prática recomendada da Amazon em vez de lançar a nossa própria.
- Estou imaginando uma situação em que os jobs são agendados em algum lugar, adicionados a uma fila e então os servidores da web podem ser cada um um trabalhador, que pode dizer "ei, vou pegar esse aqui". O Amazon Simple Workflow Service soa exatamente esse tipo de coisa, mas atualmente não sei muito sobre ele, portanto, quaisquer detalhes seriam úteis. Parece meio pesado para algo tão simples como um cron? É o serviço certo ou existe um serviço Amazon mais adequado?
Atualização: depois de fazer a pergunta, assisti ao seminário on-line do Amazon Simple Workflow Service no YouTube e notei às 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ) que vislumbrei um slide mencionando cron jobs como um aplicativo de amostra. Em sua página de documentação, " Amostras do AWS Flow Framework para Amazon SWF ", a Amazon afirma ter um código de amostra para crons:
... > Cron jobs Neste exemplo, um fluxo de trabalho de longa execução executa periodicamente uma atividade. É demonstrada a capacidade de continuar as execuções como novas execuções, de forma que uma execução possa ser executada por longos períodos de tempo. ...
Eu baixei o AWS SDK para Java ( http://aws.amazon.com/sdkforjava/ ) e com certeza enterrado em camadas ridículas de pastas há algum código java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow
).
O problema é que, para ser honesto, isso não ajuda muito, pois não é algo que posso digerir facilmente com meu conjunto de habilidades. A mesma amostra está faltando no SDK do PHP e não parece haver um tutorial que analise o processo. Então, basicamente, ainda estou procurando conselhos ou dicas.
Respostas:
Eu me inscrevi no suporte do Amazon Gold para fazer esta pergunta, esta foi a resposta:
fonte
Acho que este vídeo responde exatamente à sua pergunta - cronjobs da maneira aws (escalável e tolerante a falhas):
Usando Cron na nuvem com Amazon Simple Workflow
O vídeo descreve o serviço SWF usando o caso de uso específico de implementação de cronjobs.
A complexidade relativa da solução pode ser difícil de engolir se você estiver vindo direto de um crontab. Há um estudo de caso no final que me ajudou a entender o que essa complexidade extra compra para você. Eu sugeriria assistir ao estudo de caso e considerar seus requisitos de escalabilidade e tolerância a falhas para decidir se você deve migrar de sua solução crontab existente.
fonte
Tenha cuidado ao usar SQS para cronjobs, pois eles não garantem que apenas "um trabalho seja visto por apenas uma máquina". Eles garantem que "pelo menos um" receberá a mensagem.
De: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message
Até agora, posso pensar sobre a solução onde você tem uma instância com a instância do Gearman Job Server instalada: http://gearman.org/ . Na mesma máquina, você configura tarefas cron que estão produzindo comandos para executar sua tarefa cronjob em segundo plano. Então um de seus servidores web (workers) começará a executar esta tarefa, garantindo que apenas um a realizará. Não importa quantos trabalhadores você tem (especialmente quando você está usando o dimensionamento automático).
Os problemas com esta solução são:
fonte
A Amazon acaba de lançar novos recursos para o Elastic Beanstalk. Dos documentos :
Agora você pode criar um ambiente contendo um
cron.yaml
arquivo que configura tarefas de agendamento:Eu imagino que a segurança de executá-lo apenas uma vez em um ambiente com escalonamento automático é utilizada por meio da fila de mensagens (SQS). Quando o cron daemon dispara um evento, ele coloca essa chamada na fila SQS e a mensagem na fila é avaliada apenas uma vez. Os documentos dizem que a execução pode ser atrasada se o SQS tiver muitas mensagens para processar.
fonte
Eu me deparei com essa pergunta pela terceira vez e pensei em ajudar. Já estamos enfrentando esse dilema há algum tempo. Eu ainda realmente sentir AWS está faltando uma característica aqui.
No nosso caso, depois de examinar as soluções possíveis, decidimos que tínhamos duas opções:
cloud-init
scripts para colocar os cronjobs em execução. Claro, isso vem com um tempo de inatividade, levando a cronjobs perdidos (ao executar certas tarefas a cada minuto, como fazemos).rcron
usa. Claro, a mágica não está realmente emrcron
si mesma, está na lógica que você usa para detectar um nó com falha (que usamoskeepalived
aqui) e "atualizar" outro nó para mestre.Decidimos ir com a segunda opção, simplesmente porque é incrivelmente rápida e já tínhamos experiência com servidores da Web executando esses cronjobs (em nossa era pré-AWS).
Claro, esta solução é destinada especificamente para substituir a abordagem tradicional de cronjob de um nó, onde o tempo é o fator decisivo (por exemplo, "Eu quero que o trabalho A seja executado uma vez por dia às 5h" , ou como em nosso caso "Eu quero o trabalho B para executar uma vez a cada minuto " ). Se você usar cronjobs para acionar a lógica de processamento em lote, você realmente deve dar uma olhada em
SQS
. Não há dilema ativo-passivo, o que significa que você pode usar um único servidor ou uma força de trabalho inteira para processar sua fila. Eu também sugiro olharSWF
para escalar sua força de trabalho (emboraauto scaling
possa ser capaz de fazer o truque também na maioria dos casos).Depender de outro terceiro era algo que queríamos evitar.
fonte
Em 12 / Fev / 16, a Amazon postou em um blog sobre Agendamento de trabalhos SSH usando AWS Lambda . Eu acho que isso responde à pergunta.
fonte
Se você já tem um serviço Redis ativo, esta parece ser uma boa solução:
https://github.com/kvz/cronlock
Leia mais: http://kvz.io/blog/2012/12/31/lock-your-cronjobs/
fonte
A maneira "Amazon" é para ser distribuída, o que significa que crons volumosos devem ser divididos em muitas tarefas menores e entregues às máquinas certas.
Usando a fila SQS com o tipo definido como FIFO, cole-os para garantir que cada trabalho seja executado por apenas uma máquina. Ele também tolera falhas, pois as filas serão armazenadas em buffer até que a máquina volte a girar.
Considere também se você realmente precisa 'agrupar' essas operações. O que acontece se as atualizações de uma noite forem consideravelmente maiores do que o esperado? Mesmo com recursos dinâmicos, seu processamento pode ser atrasado ao esperar que máquinas suficientes girem. Em vez disso, armazene seus dados em SDB, notifique as máquinas sobre atualizações via SQS e crie seu feed RSS rapidamente (com cache).
Os trabalhos em lote são de uma época em que os recursos de processamento eram limitados e os serviços 'ativos' tinham precedência. Na nuvem, não é o caso.
fonte
Por que você construiria o seu próprio? Por que não usar algo como Quartz (com Clustered Scheduling). Veja a documentação.
http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering
fonte
O que fazemos é ter um servidor específico que faz parte de nosso cluster de aplicativo da web por trás de um ELB também atribuído a um nome DNS específico para que possamos executar os trabalhos nesse servidor específico. Isso também tem a vantagem de que, se esse trabalho fizer com que o servidor fique lento, o ELB o removerá do cluster e o retornará assim que o trabalho terminar e ele ficar bom novamente.
Trabalha como um campeão.
fonte
Um método para verificar se sua expressão cron funciona da maneira Amazon é executá-la por meio do comando de eventos. Por exemplo:
aws events put-rule --name "DailyLambdaFunction" --schedule-expression "<your_schedule_expression>
Se sua expressão de programação for inválida, isso falhará.
Mais recursos: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html
fonte
Se você deseja usar um serviço não AWS, pode verificar o Microsoft Azure . O Azure oferece um ótimo agendador de trabalhos .
fonte
Já que ninguém mencionou o evento CloudWatch , eu diria que é a maneira da AWS de fazer trabalhos cron. Ele pode executar várias ações, como função Lambda, tarefa ECS.
fonte