Microsserviços autônomos, filas de eventos e descoberta de serviços


15

Ultimamente, tenho lido muito sobre microsserviços e aqui estão algumas das conclusões que tirei até agora (por favor, corrija-me se estiver errado a qualquer momento).

  1. A arquitetura de microsserviços combina bem com o design orientado por domínio. Normalmente, um MS representa um contexto limitado.
  2. Se o microsserviço A exigir uma funcionalidade que reside no microsserviço B , meu modelo provavelmente está errado e A e B devem realmente ser um microsserviço / BC.
  3. A comunicação síncrona entre microsserviços (solicitações HTTP diretas) é ruim, pois desafia o objetivo dos microsserviços e introduz o acoplamento entre os componentes.
  4. A comunicação assíncrona entre serviços é desejável. Os serviços devem publicar eventos nas filas de mensagens, para que outros serviços possam se inscrever e processar sua parte do evento ou usá-lo para replicar uma parte dos dados necessários para o seu contexto. Dessa forma, os serviços podem processar solicitações até que outros serviços estejam inativos, o que não seria o caso na comunicação síncrona.
  5. Se o microsserviço A publica um evento, o microsserviço B se inscreve nesse evento e produz um novo evento como resultado, o microsserviço A não deve ser o único a processar o evento recém-criado, pois isso seria uma dependência circular. Nesse caso, devemos introduzir o terceiro microsserviço ou combinar A e B no microsserviço da AB .
  6. Micro-serviço é na verdade um termo enganador. Devemos lutar por pequenos contextos, mas isso não precisa ser o caso. O termo não deve ser "micro-serviço", mas " grande o suficiente para fazer o serviço de trabalho ".
  7. Os microsserviços nos permitem introduzir novas funcionalidades com mais facilidade e sem medo de quebrar o sistema inteiro. Isso pode ser feito introduzindo um novo serviço ou refatorando um dos existentes.
  8. Cada microsserviço deve ter seu próprio armazenamento de dados. A replicação / duplicação de dados é um comportamento desejável nessa arquitetura.

Além de confirmar minha compreensão dessa arquitetura, minha outra parte da questão está principalmente relacionada à descoberta de serviços. Se os serviços estão se comunicando de forma assíncrona e usando a fila central de eventos como o Amazon SQS, isso significa que a descoberta de serviços não tem seu lugar na arquitetura assim?

Os serviços não devem ter nenhum conhecimento sobre outros serviços no sistema. Eles conhecem apenas o contexto e os eventos que devem publicar ou assinar?

Respostas:


4

Suas conclusões parecem principalmente fundamentadas e resumem muito bem o caminho a seguir para os microsserviços.

No entanto, eu não suportaria totalmente 2, 5 e 8:

  • 2) Uma dependência simples não deve levar automaticamente a uma fusão. Você deve considerar a frequência de chamadas dependentes e também a frequência de chamadas de outros serviços.

    Portanto, se um microsserviço A exigir funcionalidade no microsserviço B com muita freqüência e o microsserviço B raramente for necessário para outros microsserviços, você deve desafiar a estrutura prevista e perguntar se não seria mais apropriado agrupar os dois microsserviços.

  • 5) é claro, você precisa evitar um ciclo interminável no tratamento de mensagens.

    Mas a adição de um intermediário não a impedirá: A poderia iniciar uma mensagem manipulada por C que lança uma mensagem manipulada por B, que lança uma mensagem manipulada por A e aqui você está preso em um loop.

    O problema não pode ser avaliado apenas considerando o nível de microsserviço: a questão é realmente sobre o tipo de mensagem e o conteúdo que pode levar ao ciclo. O gráfico que modela a distribuição e o processamento de mensagens entre os serviços deve, portanto, ser analisado como um todo (na verdade, isso pode ser complexo, portanto, você pode imaginar um microsserviço de monitoramento que detecta esses ciclos e os interrompe).

  • 8) sim, cada microsserviço deve ter seu armazenamento / banco de dados dedicado.

    É necessário um mínimo de replicação para permitir que os serviços sejam independentes. No entanto, eu não iria tão longe para dizer que a replicação é desejada: ela deve ser mantida no mínimo para evitar o acoplamento oculto por meio de processos de replicação.

    Os microsserviços são sobre acoplamentos frouxos. Às vezes, isso pode ser conseguido com mais eficiência chamando outro microsserviço para recuperar dados relacionados, em vez de replicar dados.

As duas últimas afirmações não numeradas são muito amplas para serem respondidas com firmeza aqui. Penso que a sua sugestão é um bom ponto de partida, mas que realmente depende de requisitos e restrições de arquitetura.


"Às vezes, isso pode ser conseguido com mais eficiência chamando outro microsserviço para recuperar dados relacionados, em vez de replicar dados". Portanto, não há nada errado com um pouco de comunicação síncrona e chamadas diretas (via HTTP) para buscar uma parte dos dados, como desde que essa consulta não represente transação / comando distribuído, caso contrário, não podemos garantir a atomicidade desse comando?
Robert

1
Não há solução perfeita aqui: é o acoplamento e o encapsulamento frouxos ( microservices.io/patterns/data/database-per-service.html ) para equilibrar a facilidade, mas a redundância ( microservices.io/patterns/data/event-driven-architecture .html ) no contexto da imagem geral ( microservices.io/patterns/microservices.html )
Christophe

3

Os microsserviços tratam da dissociação de diferentes domínios de funcionalidade. Cada serviço pode ser desenvolvido em um ritmo diferente, por uma equipe diferente, usando uma pilha de tecnologia diferente. Isso cria flexibilidade organizacional. O trade-off é a complexidade operacional, em que cada serviço extra cria mais uma coisa que deve ser gerenciada em um ambiente operacional. Portanto, a troca fundamental entre monólito e microsserviço não é sobre evitar dependências, mas sobre o desenvolvimento e a implantação em etapas, onde tudo deve ser enviado de uma só vez, mas com o custo de ter que ser enviado com mais frequência, porque existem mais peças móveis.

Os serviços não devem ter nenhum conhecimento sobre outros serviços no sistema. Eles conhecem apenas o contexto e os eventos que devem publicar ou assinar?

A questão da prevenção de dependência é um arenque vermelho. Você sempre terá dependências entre partes do seu produto e se elas estão em um serviço separado ou parte do mesmo código não altera o fato de que as dependências podem ser quebradas. Eles podem quebrar no nível operacional, porque um servidor principal fica inoperante, e você o gerencia por meio de práticas de redundância operacional e failover. Eles também podem ser interrompidos no nível de integração, porque as peças são alteradas de maneiras incompatíveis, detectadas por meio de testes de integração. A reprodução aleatória de código entre serviços não resolve o problema de dependências potencialmente interrompidas. As soluções para evitar dependências quebradas são redundância operacional e teste de integração, que nada têm a ver com o tamanho dos seus serviços.

Se os serviços estão se comunicando de forma assíncrona e usando a fila central de eventos como o Amazon SQS, isso significa que a descoberta de serviços não tem seu lugar na arquitetura assim?

Para responder a essa pergunta, responda primeiro a esta: por que você deseja se comunicar de forma assíncrona? É para facilitar o desenvolvimento independente de componentes separados? É para melhorar a disponibilidade operacional de um sistema 24/7? Digamos que seja o último e você deseja usar filas para replicar dados em bancos de dados locais. Bem, agora seus dados podem ficar obsoletos. Em algum momento, será muito velho. Como você lida com isso? Além disso, como você garante a disponibilidade operacional da fila, que é outro componente de tempo de execução? E como você garante a disponibilidade desses bancos de dados locais? Em vez de gerenciar um cluster de banco de dados, agora você tem vários. Sua equipe de operações pode lidar com essa carga de trabalho? E realmente, vale a complexidade, quando talvez seus usuários ficassem mais felizes com mais recursos e algumas horas de inatividade por mês se você construísse um monólito simples?

Eu acho que você entende o meu ponto. O design do sistema não se trata de certo e errado, mas de escolher entre uma grande variedade de trocas. Tudo o que está errado pode estar certo e vice-versa, se você apenas o vê no contexto certo. Seu contexto é exclusivo para você, portanto, embora possamos lhe dar uma resposta, não será a resposta. Lembre-se de quem é seu público, quais são suas necessidades e o design certo se revelará.


2
  1. A arquitetura de microsserviços combina bem com o design orientado por domínio. Normalmente, um MS representa um contexto limitado.

Discordo. DDD tende a ser muito OO. um pedido é entregue? Order.Deliver () enquanto Micro-serviços teriam DeliveryService.Deliver (order)

  1. Se o microsserviço A exigir uma funcionalidade que reside no microsserviço B, meu modelo provavelmente está errado e A e B devem realmente ser um microsserviço / BC.

Discordo, você deve tentar mantê-lo micro serviços micro. divida-os ainda menores!

  1. A comunicação síncrona entre microsserviços (solicitações HTTP diretas) é ruim, pois desafia o objetivo dos microsserviços e introduz o acoplamento entre os componentes.

Discordo. os serviços não devem se importar com quem os chama e os chamadores não se importam com a lógica ser implementada em um microsserviço.

  1. A comunicação assíncrona entre serviços é desejável. Os serviços devem publicar eventos nas filas de mensagens, para que outros serviços possam se inscrever e processar sua parte do evento ou usá-lo para replicar uma parte dos dados necessários para o seu contexto. Dessa forma, os serviços podem processar solicitações até que outros serviços estejam inativos, o que não seria o caso na comunicação síncrona.

Filas são boas. Mas seu raciocínio está errado. a única diferença entre as respostas de sincronização e async é que você espera pela sincronização. Você pode implementar chamadas no estilo RPC com filas e vários trabalhadores sem problemas.

  1. Se o microsserviço A publica um evento, o microsserviço B se inscreve nesse evento e produz um novo evento como resultado, o microsserviço A não deve ser o único a processar o evento recém-criado, pois isso seria uma dependência circular. Nesse caso, devemos introduzir o terceiro microsserviço ou combinar A e B no microsserviço da AB.

Discordo. Não é uma dependência circular porque seus microsserviços não estão acoplados. Além disso, você deseja atender a reenviar senarios, SendEmail, EmailFailed, SendAgain não precisa de 3 micro-serviços

  1. Micro-serviço é na verdade um termo enganador. Devemos lutar por pequenos contextos, mas isso não precisa ser o caso. O termo não deve ser "micro-serviço", mas "grande o suficiente para fazer o serviço de trabalho".

Discordo. Confira nano-serviços.

  1. Os microsserviços nos permitem introduzir novas funcionalidades com mais facilidade e sem medo de quebrar o sistema inteiro. Isso pode ser feito introduzindo um novo serviço ou refatorando um dos existentes.

Discordo. Sim, você se desacopla, mas a orquestração de microsserviços pode ser tão assustadora quanto qualquer projeto monolítico

  1. Cada microsserviço deve ter seu próprio armazenamento de dados. A replicação / duplicação de dados é um comportamento desejável nessa arquitetura.

Discordo. Embora você não deva compartilhar armazenamento, seus microsserviços devem tentar ficar sem estado, sempre que possível. não duplique dados, a menos que esteja a bordo


1

Suas conclusões são boas regras práticas, mas não universais. Haverá casos em que a melhor opção é violar essas regras, mesmo em um projeto greenfield. Em alguns casos, a comunicação síncrona é a melhor opção. Em alguns casos, não é bom mesclar dois serviços em um, mesmo que sejam acoplados por comunicação síncrona.

E para sua outra pergunta, a descoberta de serviço não é necessária para a comunicação baseada em fila.


0

Hum, você está apenas falando sobre programação orientada a objetos. Ou pelo menos, o que foi originalmente concebido para ser: partes independentes de código em execução que se comunicam usando mensagens.

Alan Kay concebeu o POO como modelado após sistemas biológicos, onde as células são relativamente independentes umas das outras e apenas se comunicam através de mensagens que se conectam a interfaces externas em outras células.

Então, por que paramos de pensar nisso como POO apenas porque todos os objetos não estão sendo executados no mesmo computador? Na verdade, isso é ainda mais orientado a objetos do que se eles estiverem no mesmo computador e fizer parte do mesmo aplicativo, porque se todos os objetos estiverem no mesmo aplicativo, os desenvolvedores frequentemente quebram o OOP usando variáveis ​​globais compartilhadas por todas as classes e incluindo os mesmos cabeçalhos em cada arquivo etc. Quando todos os objetos dependem do mesmo material, eles não são tão encapsulados como se fossem completamente independentes um do outro, e o encapsulamento é o ponto principal do OOP.

Por exemplo, quase tudo o que foi dito nas outras respostas são declarações de livros didáticos sobre POO.


0

Como muitas vezes encontro um entendimento errado de um conceito tão importante como Contexto Limitado e Domínio Principal, gostaria de elaborar um pouco sobre ele.

Achei extremamente lucrativo pensar em subdomínios como recursos de negócios. Capacidade de negócios é algo que sua organização faz. É uma de suas funções comerciais. Como nosso objetivo é o alinhamento entre negócios e TI , eu definitivamente quero que eles tenham uma relação 1: 1 com meus serviços técnicos .

Portanto, esse processo se resume ao seguinte. Primeiro, defino recursos de negócios de nível superior. Deve assumir a forma de substantivo e verbo (ou alguma forma derivada). Geralmente, existem menos de 10 recursos de negócios. Então eu imenso mais profundo, identificando recursos aninhados. E assim por diante, até que não haja nada para dividir. Os recursos que você usou para usar essa abordagem refletem o domínio real, a maneira real como sua organização funciona. Esses recursos serão acoplados de maneira pouco flexível, portanto, se você mapear seus serviços técnicos para esses recursos, eles serão autônomos e orientados a eventos. Esse processo é chamado de mapeamento de capacidade de negócios , mas existem outras maneiras de encontrar seus serviços, sendo o mais proeminente a análise da cadeia de valor .

Aqui está um exemplo de identificação de limites de serviço usando essa abordagem.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.