Submarino.com.br

Crontab: rodando um script a cada 15 segundos


crontab
Criei esse POST com 2 objetivos: Para compartilhar a minha idéia e quem sabe também obter novas maneiras de resolver um pequeno problema.

Problema: Digamos que você tenha que acessar uma URL qualquer (exemplo: http://localhost:3000/coletar ) a cada 15 segundos. Isso rodará um script que irá colher uma série de dados e armazena-los em banco.

Então, se você rodar um comando como este: “curl http://localhost:3000/coletar” a cada 15 segundos, resolveria meu problema. Agora, como fazer isso usando crontab ?

Se você procurar a solução na internet, encontrará algumas boas idéias como fazer um script e com alguns sleeps e um loop interno você não precisa nem de cron:

#!/bin/sh
while [ 1 ]; do
    curl "http://localhost:3000/coletar"
    sleep 15
done

Basta rodar esse script, que com um loop eterno, vai rodar o comando de 15 em 15 segundos… Agora você deve estar pensando: “Problema resolvido!” …

Na verdade, não. Os dados precisam ser coletados necessariamente a cada 15 segundos. Isso significa que se por acaso, quando for feito um request, se o servidor demorar pra responder aquela solicitação, isso pode atrasar a próxima coleta, e depois de algum tempo, o atraso só tende a piorar.

Então qual a melhor solução para este problema ?
Como eu preciso coletar a cada 15 segundos sem que uma coleta atrapalhe a outra, acho que a melhor forma de fazer isso foi adicionar no crontab do usuário:

* * * * * curl 'http://localhost:3000/coletar'
* * * * * sleep 15 && curl 'http://localhost:3000/coletar'
* * * * * sleep 30 && curl 'http://localhost:3000/coletar'
* * * * * sleep 45 && curl 'http://localhost:3000/coletar'

Com isso, os comandos serão executados independentemente a cada 15 segundos…

Então é isso…

Se você conhece alguma forma mais eficiente para fazer isso… Não deixe de  compartilhar a sua idéia comigo ;)

TwitterFacebookShare

Leia também:


16 Comentários

  1. AkitaOnRails disse:

    Oi, 3 coisas. Por que não “*/15″ para dizer “a cada 15 segundos”? Precisa ser chamada com curl? É um site externo? Se for na mesma maquina talvez um task de Rake fosse mais eficiente. Cuidado porque se por acaso uma chamada levar mais de 15 segundos elas vão encavalar, dai ou o processo é independente e isolado e aí talvez não tenha problema ou talvez o processo precise checar se não tem outra ainda em andamento (se for um task rake, usando um arquivo de pid, por exempo).

  2. AkitaOnRails disse:

    Oops falei besteira, a granularidade do cron é minuto então o que voce fez esta certo.

  3. Rafael Biriba disse:

    Sim, o meu problema foi exatamente que o cron roda minuto a minuto ! =P

    É um GET que coleta informações em alguns servidores, que apesar da rede interna, pode ter certa lentidão no tempo de resposta,…

    Por isso rodei comandos curl separados para que um não prenda o outro!

    Não acho a solução a mais eficiente, mas serviu perfeitamente para a minha necessidade, na época…

    A idéia de criar um rake até que não é ruim =)

    Abraços,

  4. Henrique disse:

    Não resolveria mandar o curl para background? Assim o retorno do comando é imediato e será esperado somente 15 segundos até a próxima iteração.

  5. Rafael Biriba disse:

    Olá Henrique,

    As tarefas do cron são executadas em background…

    Não entendi bem o que você quiz dizer… Poderia explicar de outra maneira?

    Abraços,

  6. Henrique disse:

    @ Rafael Biriba

    Me referia a solução do script com “loop eterno”.

    Pelo que entendi, o problema é que o curl não retorna enquanto o servidor não terminar de processar o request, logo, você acaba esperando 15 segundos + tempo de retorno do servidor a cada iteração… mandando o curl para background, o tempo de retorno é praticamente 0, o que resolveria o problema, ou não? :)

    []s

  7. Rafael Biriba disse:

    Correto Henrique,

    No caso do cron, funcionaria tranquilamente…

    No caso do script de loop eterno, essa sua solução serviria também… Colocando o Curl para rodar em background, usando o (&) por exemplo, ele chamaria o sleep 15 segundos, e logo em seguida chamaria o curl de novo, e assim em diante…
    Funcionaria perfeitamente também….

    Valeu pela idéia…

    Abraços,

  8. Só uma observação quanto ao loop eterno. Em teoria ele funciona, mas se der pau no processo você perderia os próximos request até perceba o problema. Colocando no cron cada 1 min, se der pau você so perde aquele pedido.

    Acho que sua solução sem loop eterno mais confiavel.

  9. Ayslan disse:

    Pessoal, sou programador, porém leigo nessa situação que nova para mim. Estou desenvolvendo um site onde há a necessidade de um script ser rodado em uma predeterminada hora do dia. A minha questão é: Não sou dono do site de hospedagem, posso utilizar o cron? Se sim, como?

  10. Rafael Biriba disse:

    Olá Ayslan,
    A empresa que hospeda o seu site não libera nenhum painel de controle ?

    Geralmente nos paineis de controle de hospedagem (como o Cpanel, por exemplo), você tem acesso a colocar script para rodar no cron.

    Agora sem isso, não tem como.
    Você pode tentar uma gambiarra:

    Coloca o script disponivel publicamente ( exemplo.com/script.php ) e tenta conseguir algum computador, na sua casa, ou na casa de algum amigo que fique ligado 24h, e coloque uma chamada no cron para chamar o seu script.

    Mas se sua hospedagem não te libera o cron, talvez esteja na hora de tentar mudar…

    Abraços,

  11. Ayslan disse:

    @Rafael Biriba

    Olá, Rafael. Realmente eu deveria ter verificado o CPanel antes de fazer a pergunta… =]

    Está lá sim.

    Valeu!

  12. Rafael Biriba disse:

    Olá Ayslan,

    É normal ter esse tipo de duvida, até porque o Cpanel tem muitas funções.

    Obrigado pela visita e volte sempre…

    Abraços,

  13. Carlos Horoshi disse:

    Bom eu não tenho esse problema pois eu utilizo o DotNetPanel na http://inter.net.br/ não tenho muita dificuldade para configurar o cron. Tirando que já existe varias tarefas pré definidas… então é só selecionar e mandar executar em tal tempo..

  14. Rafael Biriba disse:

    Entendi… Fazendo prograpanda de hospedagem aqui…

    Dúvido que eles tenham pré-definição para agendamento de 15 em 15 segundos… haha

    Boa sorte aí…

    Abraços,

  15. Carlos Horoshi disse:

    Boa Tarde…

    Não vim fazer propaganda só que no hosting que eu utilizo dá pra fazer agendamento de tarefas de 15 em 15 segundos.

    Segue ai prova ai :
    http://img225.imageshack.us/img225/8913/cron15em15.png

    Abraço. :)

Leave a Reply