Partilhar via


Utilizar a análise de domínios para modelar microsserviços

Um dos maiores desafios dos microsserviços é definir os limites dos serviços individuais. A regra geral é que um serviço deve fazer "uma coisa" — mas colocar essa regra em prática requer uma reflexão cuidadosa. Não existe um processo mecânico que produza o design "certo". Você precisa pensar profundamente sobre seu domínio de negócios, requisitos, características da arquitetura (também conhecidos como requisitos não funcionais) e objetivos. Caso contrário, você pode acabar com um design aleatório que exibe algumas características indesejáveis, como dependências ocultas entre serviços, acoplamento apertado ou interfaces mal projetadas. Este artigo mostra uma abordagem orientada por domínio para projetar microsserviços. A avaliação dos limites do serviço é um esforço contínuo na evolução das cargas de trabalho. Às vezes, a avaliação resulta em definições redefinidas de limites existentes, exigindo desenvolvimento adicional de aplicativos para acomodar as mudanças.

Este artigo usa um serviço de entrega por drone como um exemplo em execução. Você pode ler mais sobre o cenário e a implementação de referência correspondente aqui.

Introdução

Os microsserviços devem ser projetados em torno de recursos de negócios, não de camadas horizontais, como acesso a dados ou mensagens. Além disso, devem ter acoplamento solto e alta coesão funcional. Os microsserviços são acoplados de forma flexível se você puder alterar um serviço sem exigir que outros serviços sejam atualizados ao mesmo tempo. Um microsserviço é coeso se tiver uma única finalidade bem definida, como gerenciar contas de usuário ou rastrear o histórico de entregas. Um serviço deve encapsular o conhecimento do domínio e abstrair esse conhecimento dos clientes. Por exemplo, um cliente deve ser capaz de agendar um drone sem saber os detalhes do algoritmo de agendamento ou como a frota de drones é gerenciada. As características da arquitetura devem ser definidas para cada microsserviço para corresponder às suas preocupações de domínio, em vez de serem definidas para todo o sistema. Por exemplo, um microsserviço voltado para o cliente pode precisar ter desempenho, disponibilidade, tolerância a falhas, segurança, estabilidade e agilidade. Um microsserviço de back-end pode precisar ter apenas tolerância a falhas e segurança. Se os microsserviços tiverem comunicações síncronas entre si, a dependência entre eles geralmente produz a necessidade de compartilhar as mesmas características de arquitetura.

A estruturação baseada em domínio (DDD) fornece uma estrutura que pode ajudá-lo a percorrer a maior parte do caminho para um conjunto de microsserviços bem estruturados. O DDD tem duas fases distintas estratégica e tática. No DDD estratégico, está a definir a estrutura em grande escala do sistema. O DDD estratégico ajuda a garantir que a sua arquitetura permanece focada nas capacidades do negócio. O DDD tático fornece um conjunto de padrões de design que pode utilizar para criar o modelo de domínio. Estes padrões incluem entidades, agregações e serviços de domínio. Estes padrões táticos irão ajudá-lo a criar microsserviços associados e coesos.

Diagrama de um processo de design controlado por domínio (DDD)

Neste artigo e no próximo, vamos percorrer os seguintes passos, aplicando-os ao aplicativo Drone Delivery:

  1. Comece por analisar o domínio de negócio para entender os requisitos funcionais da aplicação. A saída deste passo é uma descrição informal do domínio, que pode ser melhorada para um conjunto mais formal de modelos de domínio.

  2. Em seguida, defina os contextos delimitados do domínio. Cada contexto vinculado contém um modelo de domínio que representa um subdomínio específico da aplicação maior.

  3. Dentro de um contexto vinculado, aplique padrões de DDD táticos para definir entidades, agregações e serviços de domínio.

  4. Use os resultados da etapa anterior para identificar os microsserviços em seu aplicativo.

Neste artigo, abordamos os três primeiros passos, que se preocupam principalmente com o DDD. No próximo artigo, identificaremos os microsserviços. No entanto, é importante lembrar que o DDD é um processo iterativo e contínuo. Os limites de serviço não são fixados em pedra. À medida que um aplicativo evolui, você pode decidir dividir um serviço em vários serviços menores.

Nota

Este artigo não apresenta uma análise de domínios completa e abrangente. Mantivemos deliberadamente o exemplo breve, para ilustrar os pontos principais. Para obter mais informações sobre o DDD, recomendamos o livro de Eric EvansDomain-Driven Design, o livro que apresentou o termo pela primeira vez. Outra boa referência é o livro Implementing Domain-Driven Design de Vaughn Vernon.

Cenário: Entrega por drone

A Fabrikam, Inc. está a começar um serviço de entrega por drone. A empresa gere uma frota de drones aéreos. As empresas registam-se nos serviços e os utilizadores podem requisitar um drone que venha recolher os bens para entrega. Quando um cliente agenda uma recolha, um sistema de back-end atribui um drone e notifica o utilizador do tempo de entrega estimado (ETA). Quando a entrega está em curso, o cliente pode controlar a localização do drone com um tempo de entrega estimado atualizado de forma contínua.

Este cenário implica um domínio consideravelmente complicado. Algumas das preocupações das empresas incluem o agendamento de drones, o controlo de encomendas, a gestão de contas de utilizador e o armazenamento e a análise de dados históricos. Além disso, a Fabrikam quer chegar ao mercado sem perder tempo para, em seguida, iterar rapidamente, adicionando novas funcionalidades e capacidades. A aplicação tem de operar à escala da cloud, com um objetivo de nível de serviço (SLO) elevado. A Fabrikam também espera que as diferentes partes do sistema tenham requisitos muito diferentes no que respeita o armazenamento e a consulta de dados. Todas estas considerações levaram a Fabrikam a optar por uma arquitetura de microsserviços para a aplicação de Entrega por Drone.

Analise o domínio

O uso de uma abordagem DDD ajudará você a projetar microsserviços para que cada serviço se ajuste naturalmente a um requisito de negócios funcional. Pode ajudá-lo a evitar a armadilha de deixar que os limites organizacionais ou as escolhas tecnológicas ditem o seu design.

Antes de escrever qualquer código, você precisa de uma visão panorâmica do sistema que está criando. O DDD começa modelando o domínio de negócios e criando um modelo de domínio. O modelo de domínio é um modelo abstrato do domínio de negócio. Mostra e organiza o conhecimento do domínio e fornece uma linguagem comum para programadores e especialistas em domínio.

Comece por mapear todas as funções de negócio e respetivas ligações. Provavelmente será um esforço colaborativo que envolve especialistas em domínio, arquitetos de software e outros intervenientes. Não precisa de utilizar nenhum formalismo específico. Desenhe um diagrama ou desenhe no quadro.

Ao preencher o diagrama, pode começar a identificar subdomínios discretos. Que funções estão fortemente relacionadas? Que funções são fundamentais para o negócio e quais fornecem serviços auxiliares? O que é o gráfico de dependência? Durante esta fase inicial, não está preocupado com as tecnologias ou os detalhes de implementação. Dito isto, deve observar o local onde a aplicação terá de ser integrada com sistemas externos, como CRM, processamento de pagamentos ou sistemas de faturação.

Exemplo: Aplicação de entrega por drone

Após algumas análises iniciais de domínio, a equipe da Fabrikam chegou a um esboço aproximado que retrata o domínio Drone Delivery.

Diagrama do domínio Drone Delivery

  • O envio é colocado no centro do diagrama, porque é essencial para o negócio. Tudo o resto no diagrama existe para ativar esta funcionalidade.
  • A gestão de drones também é fundamental para o negócio. A funcionalidade que está intimamente relacionada com a gestão de drones inclui a reparação de drones e a utilização de análise preditiva para prever quando os drones precisam de assistência e manutenção.
  • A análise ETA fornece estimativas de tempo para coleta e entrega.
  • O transporte de terceiros permitirá que o aplicativo programe métodos de transporte alternativos se um pacote não puder ser enviado inteiramente por drone.
  • A partilha de drones é uma possível extensão do core business. A empresa pode ter excesso de capacidade de drones durante certas horas e pode alugar drones que, de outra forma, estariam ociosos. Este recurso não estará na versão inicial.
  • A videovigilância é outra área em que a empresa poderá expandir-se mais tarde.
  • Contas de usuário, faturamento e call center são subdomínios que dão suporte ao negócio principal.

Observe que, neste ponto do processo, não tomamos nenhuma decisão sobre implementação ou tecnologias. Alguns dos subsistemas podem envolver sistemas de software externos ou serviços de terceiros. Mesmo assim, o aplicativo precisa interagir com esses sistemas e serviços, por isso é importante incluí-los no modelo de domínio.

Nota

Quando um aplicativo depende de um sistema externo, há um risco de que o esquema de dados ou a API do sistema externo vaze para seu aplicativo, comprometendo o projeto de arquitetura. Isso é particularmente verdadeiro com sistemas legados que podem não seguir as práticas recomendadas modernas e podem usar esquemas de dados complicados ou APIs obsoletas. Nesse caso, é importante ter um limite bem definido entre esses sistemas externos e a aplicação. Considere usar o padrão Strangler Fig ou o padrão Anti-Corruption Layer para essa finalidade.

Definir contextos vinculados

O modelo de domínio incluirá representações de coisas reais no mundo – utilizadores, drones, pacotes e assim por diante. No entanto, isso não significa que todas as partes do sistema tenham de utilizar as mesmas representações para as mesmas coisas.

Por exemplo, os subsistemas que lidam com reparo de drones e análise preditiva precisarão representar muitas características físicas dos drones, como seu histórico de manutenção, quilometragem, idade, número do modelo, características de desempenho e assim por diante. Contudo, na altura de agendar uma entrega, não nos preocupamos com essas coisas. O subsistema de agendamento só precisa de saber se um drone está disponível e o tempo estimado para a recolha e entrega.

Se tentássemos criar um modelo único para ambos os subsistemas, o mesmo seria desnecessariamente complexo. Também seria mais difícil para o modelo evoluir ao longo do tempo, pois as alterações teriam de satisfazer múltiplas equipas que trabalham em subsistemas separados. Portanto, geralmente é melhor criar modelos separados que representem a mesma entidade do mundo real (neste caso, um drone) em dois contextos diferentes. Cada modelo contém apenas as funcionalidades e atributos que são relevantes no respetivo contexto específico.

É aqui que entra em jogo o conceito DDD de contextos limitados . Um contexto vinculado é simplesmente o limite num domínio em que um modelo de domínio específico se aplica. Ao observar o diagrama anterior, podemos agrupar a funcionalidade de acordo com a possibilidade de várias funções partilharem um único modelo de domínio.

Diagrama de contextos delimitados

Os contextos delimitados não são necessariamente isolados uns dos outros. Neste diagrama, as linhas sólidas que conectam os contextos limitados representam lugares onde dois contextos limitados interagem. Por exemplo, o Envio depende de Contas de Utilizador para obter informações sobre os clientes e da Gestão de Drones para agendar drones da frota.

No livro Domain Driven Design, Eric Evans descreve vários padrões para manter a integridade de um modelo de domínio quando ele interage com outro contexto limitado. Um dos principais princípios dos microsserviços é que os serviços se comunicam por meio de APIs bem definidas. Essa abordagem corresponde a dois padrões que Evans chama de Open Host Service e Published Language. A ideia do Open Host Service é que um subsistema define um protocolo formal (API) para que outros subsistemas se comuniquem com ele. A linguagem publicada estende essa ideia publicando a API em um formulário que outras equipes podem usar para escrever clientes. No artigo Designing APIs for microservices, discutimos o uso da especificação OpenAPI (anteriormente conhecida como Swagger) para definir descrições de interface agnósticas de linguagem para APIs REST, expressas em formato JSON ou YAML.

Para o resto desta jornada, vamos nos concentrar no contexto limitado do Shipping.

Próximos passos

Depois de concluir uma análise de domínio, o próximo passo é aplicar DDD tático, para definir seus modelos de domínio com mais precisão.