Introdução
Estou lendo o livro Criando Microsserviços escrito por Sam Newman da editora O'Reilly. Este livro aborda as principais vantagens e desvantagens dos microsserviços, e se esta é mesmo a arquitetura que você quer seguir para o seu sistema, e um dos tópicos abordados é como esses sistemas conseguem se conversar.

Capa do livro Criando Microsserviços.
Partindo do princípio que cada microsserviço deve ser o mais independente possível, acaba sendo contraditório dizer que eles devem se comunicar. Se levarmos ao pé da letra o que o autor do livro diz na parte de acoplamento entre serviços, deveríamos fazer o mínimo de comunicação possível entre eles.
Acredito que é inevitável nossos serviços não se comunicarem, e muito provavelmente você também já que está lendo este artigo. Vou mostrar as maneiras que aprendi no livro e minha opinião sobre elas.
Primeiramente, precisamos entender que as comunicações podem ser separadas em duas grandes categorias, síncronas bloqueantes e assíncronas não bloqueantes.
Síncronas bloqueantes
Nessa categoria, um microsserviço envia uma requisição para outro e fica aguardando a resposta antes de continuar a execução, mantendo a operação bloqueada durante esse tempo.
Se você trabalha na área ou tem um pouco mais de experiência, muito provavelmente já está familiarizado no padrão Requisição-Resposta, é a exatamente assim que ocorre a comunicação síncrona. Podemos trabalhar com HTTP ou RPC.
Não se confunda, o async
e await
que você utiliza na sua linguagem de programação para
fazer uma requisição, no contexto de seu microsserviço é uma comunicação assíncrona não bloqueante, mas como um todo
para seu sistema, essa interação entre eles é bloqueante, pois o uso do await
indica que aquela
linha de código deve ser executada antes de partimos para a próxima instrução.
O acoplamento entre os sistemas é bi-direcional, ou seja, ambos microsserviços se comunicam, isso leva a principal desvantagem na minha opinião, que é no caso de uma falha, não ser possível fazer uma nova tentativa.
Assíncronas não bloqueantes
Já a comunicação assíncorna, o microsserviço pode seguir adiante com seu processamento sem esperar um retorno. Aqui as coisas se complicam um pouco, podemos de diversas maneiras fazer isso:
Requisição-Resposta
O conceito é muito semelhante ao síncrono, mas a diferença é que a resposta é recebida imediatamente, independente do processamento ter terminado ou não. Podemos trabalhar também com brokers com base em filas neste cenário.
Orientado a eventos
Nesse estilo de comunicação um serviço dispara apenas o fato que este evento ocorreu, enquanto outros serviços ficam a espera destes eventos junto com suas informações (mensagens).
Existe baixo acoplamento entre os serviços, pois um broker como o RabbitMQ que vai ser responsável por receber e transmir estes eventos. Também se discute bastante quais informações devem ser compartilhadas entre os eventos, pois dependendo delas, é possível aumentar o acoplamento entre os sistemas ou ter mais chances de breaking changes.
Comunicação por dados em comum
Essa é a mais controversa, pois alguns podem dizer que isso não é uma comunicação. Ela é feita se alterando uma tabela no mesmo banco de dados compartilhado entre 2 microsserviços, e é exatamente aí que entra a controversa, pois o recomendado seria que cada microsserviço tivesse seu próprio banco de dados, mas isso é uma discussão muito mais complexa.
Este estilo de comunicação pode ser feito de outras maneiras também, como por exemplo arquivos em comum.
Na minha opinião, esse modelo de comunicação não é tão ruim quanto parece ser, ele é simples e cumpre seu papel de comunicar dois serviços.
Qual devo escolher?
Como tudo quase tudo em T.I, você já deve saber a resposta: Depende!
Se seu sistema é simples e você acredita que no caso de uma falha possa simplesmente fazer um novo pedido, ok, não há nada de errado em usar um padrão síncrono Requisição-Resposta. Já se você acredita que é crítico termos que executar novamente uma ação sem o input de um usuário, gravar as requisições em uma fila é importamente para se realizar novas tentativas de comunicação.
Acredito também que não devemos ter medo de fazer mudanças. Se o seu sistema cresceu e você acredita que é o momento de alterar o estilo de comunicação entre seus microsserviços, avalie se a mudança trará benefícios reais.
Tome decisões baseado no que for melhor para seu time (ou seja, eles também devem estar familiarizados com a tecnologia) e o que proporcionar a escalabilidade de sua aplicação, não porque é a última tecnologia do momento ou é sua favorita.