Este documento busca mostrar como deve ser feita a separação dos componentes cloud, para que atendam tanto a mensageria de eventos entre microsserviços, quanto subscrição de comandos.
Tentamos esclarecer algumas das vantagens do modelo proposto.
Essas são algumas das perguntas que levantaram a necessidade desse Spike:
Abaixo segue tabela comparativa entre os benefícios e riscos de cada proposta:
Critério (Broker) | Proposta 1 - Economia | Proposta 2 - Robustez |
---|---|---|
Segurança | Atende Totalmente | Atende Parcialmente |
Monitoramento | Atende Parcialmente | Atende Totalmente |
Isolamento | Atende Parcialmente | Atende Totalmente |
Customização | Atende Parcialmente | Atende Totalmente |
Economia de Recursos | Atende Totalmente | Não Atende |
Simplicidade de Manutenção | Não Atende | Atende Totalmente |
Existem dois modelos a ser entendidos aqui. Um ocorre quando o cliente opta pelo ambiente exclusivo, e outro compartilhado.
Figura 1 - Overview de uma arquitetura em um ambiente cloud compartilhado entre clientes +
message broker com acesso externo desabilitado
Figura 2 - Overview de uma arquitetura em um ambiente cloud exclusivo +
message broker com acesso externo habilitado
Já tínhamos a premissa de que para a subscrição de eventos o RabbitMQ deveria estar exposto para acesso externo. Entretanto, percebemos que essa mesma também pode existir para um cenário de microsserviços, onde o cliente tenha parte destes rodando na sua infraestrutura, e parte em cloud.
Levamos em consideração também que pode ser bastante vantajoso para o cliente subscrever suas próprias aplicações nos nossos eventos.
As conexões externas devem ser realizadas através de AMQPS, que nada mais é do que é o protocolo AMQP através de TLS.
Nessa modelagem, existiu também uma proposta sobre como poderia funcionar o modelo de subscrição dos microsserviços.
A base aqui é a arquitetura de publish/subscribe, em sua maneira mais simples, sem utilizar tópicos ou roteamentos mais complexos. Se existir uma necessidade de negócio para justificar uma complexidade maior, essa deveria passar pelo nosso comitê para um entendimento mais aprofundado.
Cada Exchange representa uma informação de eventos realizados que outros sistemas podem vir a se interessar (não necessariamente de CRUD, pode ser um processo que foi realizado). Cada API tem sua fila própria, para aquele evento, e a mesma é subscrita na Exchange.
O escalonamento pode ser feito por N instâncias da mesma API lendo a mesma fila.
Na arquitetura proposta acima, o API Mirror só existe dentro do modelo exclusivo, e por isso somente necessita um login (O do VHOST do tenant a qual pertence).
Se existir alguma mudança, e ele precisar ter um acesso no modelo compartilhado, continua sendo ainda apenas a conexão com o VHOST default ("/").
Supondo ainda que precisasse acessar N VHOSTS, aí faria sentido ele ter um login com perfil de administrador, com acesso a todos, que muda sua senha periodicamente.
Essa proposta busca uma arquitetura mais simplificada do que a apresentada anteriormente, porém mais robusta, buscando unificar o mesmo desenho para cenários compartilhados e exclusivos.
Isso garante que, até mesmo no ambiente compartilhado, teremos um nível maior de isolamento.
Conseguiremos, também, monitorar exatamente o que está acontecendo para cada cliente.
O ponto negativo é um número maior de conexões abertas, o que pode acarretar em uma necessidade de maior escalonamento, horizontal ou vertical. Consequentemente, maior custo de infraestrutura Cloud. Como contra ponto disso, podemos pensar que essas conexões vão "abrir e fechar", e em um cenário que temos muitas simultâneas quer dizer que provavelmente está sendo lucrativo para a companhia.
Figura 3 - Overview de uma arquitetura simplificada com a coexistência ambiente cloud compartilhado e exclusivo seguindo as
mesmas regras para o message broker (acesso externo habilitado)
Na arquitetura proposta acima, o API Mirror utilizará um login único, que possui os acessos aos VHOSTS necessários.
Essa mesma ideia se aplica à conexão dos microsserviços com o broker: Um login que possui os acessos devidos.
O consumidor, para se conectar externamente ao broker, tem um login separado que acessa apenas o seu próprio VHOST
No RabbitMQ, a autenticação é feita com base no usuário e senha de um determinado VHOST que se deseja conectar.
Ele possui dois níveis de autorização, sendo que isso é facilmente configurável através do console de administração.
Níveis:
É possível cadastrar os chamados "Alternative Authentication and Authorisation Backends". Isso é feito através de plugins do Rabbit.
O Plugin rabbitmq-auth-backend-http é o oficial para isso, e ele exige que o server para o qual aponta respeite o padrão especifico de autenticação do Rabbit.
Eles também possuem o plugin rabbitmq-auth-backend-oauth2 para trabalhar com IDPs no padrão Oauth 2.0. Existe uma nota informando que o mesmo ainda está em um estágio experimental, e, no momento de escrita desse documento, existem testes unitários quebrando na master.
Não encontrei plugins específicos para o formato esperado pelo RAC (OpenID).
Customizações nos comportamentos dos plugins exige conhecimento de Erlang.
Detalhes na implementação ou utilização de ambos plugins exigem um estudo/spike mais aprofundado voltado para tal.
https://www.rabbitmq.com/access-control.html
https://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html
https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html
https://www.rabbitmq.com/ssl.html
https://www.cloudamqp.com/blog/2017-12-29-part1-rabbitmq-best-practice.html
1 comentário
Luciano De Araujo
Francisco, em relação a suprimir o tenantId da mensagem, de quem seria esta responsabilidade? Do aplicativo?
Conforme definido na reunião do comitê de e documentado aqui, o tenantId é obrigatório nas mensagens trafegadas entre os microsserviços.