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 😉

Share
  • 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).

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

  • 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,

  • Henrique

    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.

  • 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,

  • Henrique

    @ 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

  • 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,

  • 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.

  • Ayslan

    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?

  • 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,

  • Ayslan

    @Rafael Biriba

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

    Está lá sim.

    Valeu!

  • Olá Ayslan,

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

    Obrigado pela visita e volte sempre…

    Abraços,

  • Carlos Horoshi

    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..

  • 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,

  • Carlos Horoshi

    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. 🙂

  • Pingback: Net-sftp: Solução para timeout durante o upload | Rafael Biriba Blog()

  • Estou com um tema Zenko Magazine 1.6 o mesmo que vc utiliza.
    mas o servidor e windows e nao da para o comando 755.

    ————-
    ae as imagens nao aparece que devo fazer

    • As imagens que vocês pergunta, seriam os thumbs ?

  • Estou com um problema.
    Tenho um .sh que executa um zenity, ex:

    #!bin/bash
    zenity –info –text=’Bem vindo’

    Gostaria de colocar este script para rodar a cada minuto, fiz o exemplo citado acima e não funciona:

    * * * * * /home/dinho/script.sh

    O mesmo já está com permissão para executar e tudo mais, tanto que é executado no início da sessão