Muitos dos sites de elevado desepanho criados hoje em dia, por vezes, necessitam de realizar tarefas que levam uma quantidade relativamente grande de tempo, tal como a geração de pdfs ou o envio de emails ou a importação de arquivos. Algumas dessas tarefas exigem muita memória, outras apenas requerem demasíado tempo para concluirem. De forma a construir uma arquitetura escalável que nos permita processar em background estas tarefas recorremos a um Message Broker, mais concretamente ao RabbitMQ e a uma implementação em PHP com a framework Symfony 2 para realizar o processamento e geração dos ficheiros PDF de forma eficiente.
O que é o RabbitMQ?
RabbitMQ é um message broker que permite enviar mensagens através de um processo chamado de producer/produtor e posteriormente ler as mensagens na fila de espera através de um consumer/consumidor. Neste processo de envio e leitura de mensagens encontram-se 3 conceitos chave:
- exchange – são pontos de entrada para todas as mensagens publicadas pelos produtores.
- queue – Fila onde são armazenadas as mensagens.
binding – bindings são conjuntos de regras para interligar queues e exchanges, define para que queue deve ser enviada a mensagem recebida no ponto de entrada.
As mensagens nas filas são armazenadas de forma independente. Cada mensagem contém a informação necessária ao seu processamento. Uma mensagem pode ser um objecto serializado, um email a enviar, uma imagem, ou outro elemento qualquer.
Representação do processamento das mensagens
Vantagens da utilizar o RabbitMQ
Através utilização do RabbitMQ foi possível compreender as seguintes vantagens na nossa aplicação:
- Scalability – Um consumidor, lê uma mensagem da fila, mas não tem que existir necessáriamente apenas um consumidor. Por isso podemos criar multiplos consumidores quantos nos seja necessário.
- Clustering – Multiplos servidores RabbitMQ na rede local podem ser agrupados de forma a criarem um único broker logico.
- Highly Available Queues – As filas podem ser clonadas para multiplas máquinas num cluster, garantindo que, mesmo em caso de falha de hardware as mensagens são guardadas.
- More responsive applications – através da delagação das tarefas/processamento complexo ao RabbitMQ a nossa aplicação pode focar-se em realizar as tarefas realmente importantes para o utilizador ou para o serviço.
Instalação
Adicionar as sources ao ubuntu
$ deb http://www.rabbitmq.com/debian/ testing main
Instalar
Verificar o estado
$ sudo rabbitmqctl status
Instalar o plugin de administração
$ sudo rabbitmq-plugins enable rabbitmq_management
Abrir o painel de administração em http://your-server.name:15672
Criar o consumidor
<?php
namespace Es\InvoiceBundle\Service;
use OldSound\RabbitMqBundle\RabbitMq\ConsumerInterface;
use PhpAmqpLib\Message\AMQPMessage;
class PdfGeneratorConsumer implements ConsumerInterface
{
private $pdf_generator;
public function __construct(LoggableGenerator $pdf_generator)
{
$this->pdf_generator = $pdf_generator;
}
public function execute(AMQPMessage $msg)
{
//deserializar a mensagem
$msg = unserialize($msg->body);
$url = $msg['url'];
$output = $msg['output'];
//realizar processamento
$this->pdf_generator->generate($url, $output);
//confirmar o processamento completo com return true
return true;
}
}
O RabbitMQ é sem dúvida uma ferramente muito poderosa, este é apenas um artigo simples de configuração e implementação em PHP e como tal recomendo a leitura dos tutoriais disponíveis da página oficial: