Criar daemons em PHP

por adlerparnas

Fala Pessoal!

Meu nome é Adler Parnas, depois de um tempo OFF, venho falar de como criar daemons utilizando PHP.

Todos nós, programadores PHP, sabemos que essa linguagem funciona muito bem rodando sobre um servidor WEB (Apache, IIS, etc..), mas quantas vezes precisamos rodar uma rotina de backup automática no servidor ou mesmo criar um daemon para monitorar uma fila? OK! Podemos criar scripts em SHELL, Phyton, PERL e etc…, mas eu domino PHP!

A execução de um script PHP pela linha de comandos é extremamente fácil! Basta que você chame o executável do PHP passando como parâmetro o nome do arquivo a ser executado.

#executando script pela linha de comandos (GNU/Linux)
$ php meu_script.php

Este tipo de recurso, nos permite por exemplo criar scripts que serão executados no CRON de um servidor, resolvendo por exemplo a necessidade de rotinas de backup.

Outra possibilidade é criar daemons( programas que rodam em background no servidor num loop infinito) para monitorar portas ou filas de requisições. Como um daemon é um loop infinito, nada melhor que um while para fazer com que sua rotina execute eternamente.

<?php
while(TRUE){

// Faça sua mágica aqui!!

}
?>

O grande pulo do gato, para que você não acabe com os recursos do seu servidor, você DEVE incluir a chamada da função sleep, para que seu servidor respire a cada iteração.

<?php
while(TRUE){

// Faça sua mágica aqui!!
sleep(10);  //sua rotina será executada a cada 10 segundos
}
?>

Como disse, este tipo de recurso é ótimo para monitoramento de portas ou filas (usei para isso :D). Então digamos que você compre um plano de hospedagem de site que lhe permita o acesso via SSH, assim você poderá executar seu daemon. O único problema é que quando você finalizar a sessão, todos os aplicativos executados por você também serão finalizados. Isso ocorre porque os aplicativos executados são filhos da sua sessão. Para resolver isso utilizei um script que executa meu daemon e finaliza, deixando o daemon “órfão”, deixando que eu finalize minha sessão SSH, sem que meu daemon pare de rodar.

Este é um exemplo de um daemon em PHP que a cada 10 segundos escreve num arquivo na pasta /tmp/ do meu servidor (GNU/Linux):


<?php
/**
* Programa daemon.php que escreve na diretório /tmp
*/

// guardando a hora de início da execução do daemon
$init = microtime(true);

//iniciando loop infinito
do{
 exec('echo "Estou rodando a '.(microtime(true) - $init).' segundos" >> /tmp/daemon.log');

 // adormecendo o daemon por 10 segundos
 sleep(10);
}while(TRUE);
?>

Para chamar meu daemon, sem que ele morra no final da sessão, escrevi uma script que utiliza a função proc_open para iniciar o processo:

<?php
/**
* Programa para executar o daemon
*/

//array de pipes, parâmetro obrigatório da função proc_open
$array_pipes = array();

//executando o daemon
proc_open("php daemon.php &", array(), $array_pipes);

exit;
?>

É isso ai pessoal! Espero que essa dica seja útil a muitos de vocês como foi para meu projeto. Caso tenha dito algo errado, favor me corrijam! Postem suas dúvida e/ou comentários!

PS.: O Próximo artigo será como criar daemons no Code Igniter! 😀

Anúncios

17 Responses to “Criar daemons em PHP”

  1. Só um detalhe. Sua idéia para criar daemons no PHP é ótima. Também faço muitas rotinas de administração no PHP assim. Só tenho observado um consumo grande de recursos após alguns dias rodando. Mas não é nada monstruoso também não.

    Uma observação que queria fazer é que, para rodar o seu script sem que ele seja fechado após a finalização da sua sessão, você pode utilizar o comando nohup. Com ele, mesmo que sua sessão feche, o processo continuará rodando e ainda envia as saídas do STDOUT pra um arquivo nohup.out no mesmo diretório de onde você chamou o processo.

    Sua chamada ficaria assim:

    user@server:~$ nohup /usr/local/bin/php daemon.php

  2. Esse artigo foi fantástico! Há muito tempo eu procurava algo do gênero. Esse método transforma um script PHP, que normalmente responde a uma requisição HTTP, em uma típica thread, e a partir daí, muitas possibilidades se abrem. Exemplos de uso são monitores, filas de processamento, jobs noturnos, importações etc. Tudo automático, sem a necessidade de criação de agendamentos etc etc.
    A minha contribuição para esse artigo é informar que é possível, usando ajax, disparar um desses processos, dando ao client a possibilidade de controlar tais processos. Não há a necessidade de se chamar scripts por shell, executar comandos ou coisas do gênero. Com ajax, o client pode disparar um requisição HTTP que é um desses códigos com while e sleep. A comunicação entre a aplicação e essas threads pode ser feita através de arquivos ou banco de dados. Desse modo, seria possível um usuário verificar se o processo está vivo, iniciá-lo, pará-lo etc. Uma infinidade de novas aplicações se abrem por conta disso.
    Parabéns pelo artigo, adlerparnas!!

    • Luís! Muito obrigado pelo comentário e pela contribuição!

      Sobre executar os daemon, pelo que ví, seria necessário a execução via shell, ou então teria de alterar o tempo de execução do PHP no início do script!

  3. Exato. Alterar o tempo de execução no início permitiria que a thread fosse controlado por Ajax e arquivos externos e toda a graça seria possível!

  4. DICA:
    Se você colocar:
    #!/usr/bin/php

    no topo do arquivo tu não precisa rodar o programa usando o comando php:
    user@server:~$ php meuprograma.php
    tu pode chamar ele diretamente:
    user@server:~$ meuprograma.php

  5. utilizando set_time_limit(0) seu script vai rodar eternamente + ignore_user_abort(true) vai ignorar quando a sessão for finalizada, então basta rodar uma vez seu script com o loop e ele ficará lá em background para sempre.

  6. Caros, sei que o tópico não é recente porém preciso muito rodar um script que enviará um email diário para o usuário.
    Porém preciso que o mesmo envie este email automáticamente sem a necessidade de entrar no sistema via URL, tentei aplicar o seu exemplo mas não obtive sucesso.
    Poderias me ajudar a achar o erro?

    Obs.: o sistema roda em um servidor contratado, talvez necessite de algum recurso adicional instalado no servidor?

    Att
    Ederson dos Santos

  7. Ederson, depende do servidor que você está hospedando. Algumas hospedagens, por segurança, impedem comandos como set_time_limit(0) para que scripts não consumam recursos “eternamente”. (eu faria o mesmo no lugar deles…)
    Há serviços de hospedagens que dão recursos para agendamento de tarefas. Eu, por exemplo, utilizo um agendador de tarefas HTTP. Configuro uma página PHP para executar diariamente, e em seu código envio e-mails. Quando não temos controle do servidor, ficamos reféns das ferramentas disponibilizadas pela empresa de hospedagem.

    Gaido

  8. Olá, preciso de um script que monitore uma tabela e retorne para página php algo que indique que houve uma alteração. Tentei usar este exemplo mas o seguinte erro é retornado: Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\Servidor\scriptMonitor.php on line 64

    • Olá Marcus Ramon!
      Primeiramente gostaria de agradecer a visita ao meu blog.

      Pelo que ví você está em ambiente Windows correto? Todo esse artigo foi baseado em ambiente linux, por isso algumas coisas podem não estar funcionando.

      Quando você diz, “monitore uma tabela e retorne para página php” você quer dizer: “executar um script php” ou “resonder para o navegador”?

      Sobre a mensagem de erro é que por padrão o PHP vem configurado para executar uma requisição por 30 segundos, você teria que modificar essa confguração no php.ini ou utilizando a função set_time_limit(0) no início do seu script

      Espero ter ajudado, caso possua mais dúvidas estou a disposição.

      • Parabéns pelo seu Blog e muito obrigado pela rápida resposta!

        Sim, estou usando ambiente windows para teste, mas o servidor que irei utilizar é um grátis em linux que encontrei. Testei neste servidor e ao invés de dar o erro, não aconteceu nada.

        Mas de qualquer forma, vou fazer esse monitoramento direto da minha aplicação, sei que não é o mais recomendado, mas no momento não estou preocupado com os recursos do servidor!

        Valeu!

  9. Alguém sabe como fazer ele parar??
    Coloquei um aqui pra rodar na minha maquina virtual e ele n para mais, to revirando a net pra achar como para e n achei nada até agora..
    da uma força ai..

    • Fala Rodrigo!
      Se você estiver no linux, pode rodar o comando “ps ax” e identificar o processo rodando.

      Este artigo mostra somente o básico para criar deamons em PHP, mais você pode/deve criar todas as funcionalidades que você precisa. Por exemplo, criar uma validação a cada execução pra saber se é pra parar ou continuar executando.

      Muito obrigado pelo comentário. Visite meu blog novo http://adlerparnas.com/blog/ estou postando novos artigos lá.

Trackbacks

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: