Nós, profissionais da área de TI, sejamos arquitetos de sistema, gestores, analistas de infraestrutura ou desenvolvedores, estamos habituados a propor soluções com uso de um modelo online compartilhado, com um fluxo ou workflow totalmente baseado em controle por status, ou sequencial com concorrência transacional, para garantir a atomicidade.
Esse modelo convencional e mais conservador é de fácil compreensão por parte de profissionais, sejam eles de TI ou não, por refletir exatamente o modelo conceitual discutido em brainstorm e blueprint nas fases iniciais dos projetos, quando todo fluxo é direcionando para o banco de dados, sendo essa camada responsável por garantir a atomicidade, o estado e o controle do fluxo de dados.
No entanto, quando nos deparamos com problemas de performance, desempenho e tempo de resposta, a primeira solução que vem à mente é escalar o hardware, mas isso impacta diretamente no resultado, aumentando o custo por transação.
Pense grande para ser grande
Bela frase, não? Recentemente, fiz uma pesquisa para entender como grandes players de tecnologia efetuam o seu processamento e conseguem otimizar seus recursos de infraestrutura frente à evolução do negócio. Pense grande para ser grande, distribua o processamento com micro-serviços divididos e/ou agrupados por responsabilidade com workflows desacoplados em nível de infraestrutura com serviços de barramento.
O barramento de serviços utiliza o conceito de processamento por filas, no qual o conteúdo de cada item da fila pode ser apenas a chave ou o identificador de um objeto a ser processado. O formato dependerá da tecnologia empregada no projeto.
Apresento na figura 1 um exemplo de implementação de fila utilizando um pipeline baseado em troca de estado, no qual em cada fila há um agente responsável por:
- Efetuar a aquisição da informação na fila, garantindo atomicidade;
- Invocar o serviço que irá processar a regra de negócio;
- Persistir os dados no banco de dados;
- Analisar o resultado do processamento;
- Tomar a decisão de passar o objeto para o próximo Data Bus – Pipe.
Figura 1 – exemplo de workflow distribuído em serviços de barramento
Figura 2 – exemplo de implementação do processo Agent com processamento assíncrono
Atomicidade transacional no barramento de serviços
Manter a atomicidade transacional no serviço de barramento é a característica mais importante do serviço de barramento, e isso pode ser garantido no nível de aplicação pelo agente responsável por retirar e inserir itens na fila. No entanto, essa não é a opção recomendada, pois, quando houver a necessidade de escalar o serviço de barramento, a quantidade de agentes apontando para a mesma fila poderá gerar erros de persistências, possibilitando que mais de um agente leia a mesma informação do barramento.
Para resolver o problema de atomicidade, deve-se definitivamente optar por filas atômicas, nas quais o controle de inserção e retirada de um item da fila fique a cargo do serviço de barramento; assim, quando houver necessidade, o número de agentes de serviços poderá ser elevado ao máximo necessário, aproveitando a capacidade de processamento e o uso balanceado dos recursos de hardware disponíveis.
Figura 3 – exemplo de utilização de fila atômica com mais de uma instância do agente
No mercado, há diversas opções de tecnologia para uso do serviço de barramento, opções de instalação Stand-Alone, Clusters e Cloud Service. Seguem abaixo algumas delas:
- Amazon SQS
- IBM WebSphere MQ
- Microsoft BizTalk
- Microsoft Azure BizTalk
- Microsoft Azure Service Bus
- Microsoft Message Queue
- Microsoft SQL Service Broker
- RabbitMQ (Open source / Mozilla Public License v1.1)
Esses produtos oferecem diversos tipos de fila, como queue, tópicos, retransmissões, hubs de evento e notificação. Escolha o produto e o tipo de fila que irão se adequar melhor à sua necessidade de negócio.
Conclusão
Há diversas maneiras, cenários e tecnologias com características diferentes para aplicar o uso de filas com serviços de barramento. Otimize seus recursos, e pense grande para ser grande!