Celery + RabbitMQ para gerenciar filas de tarefas no Ubuntu / Mateus Pádua Web Developer
Celery + RabbitMQ para gerenciar filas de tarefas no Ubuntu
O Celery é um Python Package Index (PyPi) que pode ser instalado via pip. Com ele conseguimos executar tarefas(tasks) em segundo plano e assim não bloqueamos nosso programa em execução, melhorando assim a experiência do usuário, que não precisa ficar esperando determinada tarefa terminar, como por exemplo um envio de email que muitas vezes é um pouco demorado.
Importante: Antes de instalar o Celery crie um virtualenv, para instalar o virtualenv clique aqui
$ virtualenv --no-site-packages myvenv
Para instalar o Celery digite:
Celery precisa de um message broker para funcionar. O broker é um intermediário que gerencia a fila de tarefas e as envia para os Celery workes executá-las. Para instalar o RabbitMQ basta digitar:
Importante: Após a instalação o serviço RabbitMQ é iniciado automaticamente.
Os dois comandos abaixo não são necessários neste tutorial, use-os caso seu serviço RabbitMQ precise ser inicializado ou parado manualmente:
Inicia o serviço em background:
Nunca use Kill para parar o RabbitMQ, invés disso, use o comando abaixo:
Abaixo uma imagem simplista de como funciona a fila de tarefas que serão executadas.
Dica: se achar necessário crie uma pasta chamada celery_hello por exemplo, apenas para para isolar nossos testes:
$ mkdir cellery_hello
$ cd cellery_hello
Agora crie um arquivo chamado myapp.py e cole o conteúdo abaixo:
backend='amqp'
print 'olá celery'
return 'nao passa nada para o backend'
def numeros_primos(x):
Nas 7 primeiras linhas nós configuramos nossa app Celery, passando o nome 'myapp', o broker que é nosso gerenciador de mensagens e também um backend que é onde as respostas de nossas tarefas serão armazenadas, existem muitos outros backends como por exemplo: SQLAlchemy/Django ORM, Memcached, Redis, AMQP (RabbitMQ), e MongoDB.
A função print_hello() não armazena nenhum resultado pois tem como objetivo apenas imprimir na tela 'olá celery', por isso passamos o parametro ignore_result para a task.
A função numeros_primos() e add() terão seus resultados armazenados no backend e poderão ter seus respectivos retornos consultados pelo método .get() que usaremos logo abaixo.
Agora vamos testar nossas tasks:
Abra duas janelas(dois consoles) e na primeira digite:
$ celery -A myapp worker -l info
Na segunda tela digite:
>>> from myapp import print_hello, numeros_primos, add
>>> print_hello.delay().get()
Percebe-se que nada é impresso na tela, isso por causa da propriedade ignore_result=True, mas acredite ela foi executada em background,
Agora vamos rodar a task add:
>>> add.delay(10, 15).get()
Repare que neste caso, teve uma saída, isso porque o resultado ficou armazenado no backend e pode ser consultado através do .get()
Agora vamos rodar a task numeros_primos() que vai nos possibilitar descobrir alguns novos recursos do Celery:
>>> primos = numeros_primos(20000)
Após executar a linha acima a console ficará "travada" (por pouco tempo) e você não conseguirá fazer mais nada até que a função seja executada por completo. Com isso percebemos o porque utilizar o Celery, pois com ele conseguimos executar a função e ainda podemos continuar executando outros comandos, pois a task numeros_primos está sendo executada em segundo plano, para testarmos isso, rode os comandos abaixo:
>>> primos = numeros_primos.delay(20000)
>>> primos.ready()
Agora aguarde um pouco e digite primos.ready() novamente e você receberá True como resposta. Digite também primos.get() para ver todos os números primos calculados:
>>> primos.get()
Celery é uma ótimo opção para aplicativos que precisam de performance e não podem ficar esperando a execução de tarefas. Com isso conseguimos melhorar a experiência dos usuários.