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 apenas uma coisa, mas colocar essa regra em prática requer uma reflexão cuidadosa. Não há nenhum processo mecânico que produza o projeto correto. 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 que exigem mais desenvolvimento de aplicativos para acomodar as alterações.

Este artigo usa um serviço de entrega por drone como um exemplo em execução. Para obter mais informações sobre o cenário e a implementação de referência correspondente, consulte Projetar uma arquitetura de microsserviços.

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, você define 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. Esses padrões táticos ajudam você a projetar microsserviços que são acoplados de forma flexível e coesos.

Diagrama que mostra um processo 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 mais informações sobre DDD, recomendamos Domain-Driven Design, de Eric Evans, o livro que introduziu o termo pela primeira vez. Outra boa referência é 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 inclui um domínio bastante complexo. Algumas das principais preocupações comerciais incluem o agendamento de drones, o rastreamento de pacotes, o gerenciamento de contas de usuários e o armazenamento e análise de dados históricos. A Fabrikam também pretende chegar ao mercado rapidamente e iterar com celeridade, adicionando novas funcionalidades e capacidades adicionais. O aplicativo deve operar em escala de nuvem e atender a um objetivo de alto nível de serviço. Além disso, a Fabrikam espera que diferentes partes do sistema tenham requisitos variados para armazenamento e consulta de dados. Essas considerações levam a Fabrikam a adotar uma arquitetura de microsserviços para o aplicativo Drone Delivery.

Analise o domínio

Uma abordagem DDD ajuda 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ê deve ter uma compreensão de alto nível do sistema que você cria. 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. Ele destila e organiza o conhecimento do domínio e fornece uma linguagem comum para desenvolvedores e especialistas em domínio.

Comece mapeando todas as funções de negócios e suas conexões. Esse esforço pode ser uma colaboração que inclui especialistas em domínio, arquitetos de software e outras partes interessadas. Não precisa de utilizar nenhum formalismo específico. Desenhe um diagrama ou desenhe no quadro.

Ao preencher o diagrama, você pode começar a identificar subdomínios discretos. Que funções estão fortemente relacionadas? Que funções são essenciais para o negócio e que funções prestam serviços auxiliares? Qual é o gráfico de dependência? Durante esta fase inicial, não está preocupado com as tecnologias ou os detalhes de implementação. Dito isso, você deve observar o local onde o aplicativo precisa se integrar a sistemas externos, como gerenciamento de relacionamento com o cliente, processamento de pagamentos ou sistemas de cobrança.

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 que mostra o 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 possa vazar para o aplicativo. Esse tipo de vazamento pode comprometer o projeto arquitetônico. É especialmente comum com sistemas legados que não seguem as práticas recomendadas modernas e podem usar esquemas de dados complicados ou APIs desatualizadas. Nestes casos, é importante estabelecer um limite bem definido entre o sistema externo e a aplicação. Considere usar o padrão Strangler Fig ou o padrão Anti-Corruption Layer para impor esse limite.

Definir contextos delimitados

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.

O conceito DDD de contextos limitados entra em jogo aqui. Um contexto delimitado define o limite dentro de um domínio onde um modelo de domínio específico se aplica. Referindo-se ao diagrama anterior, você pode agrupar a funcionalidade com base no fato de diferentes funções compartilharem o mesmo modelo de domínio.

Diagrama que mostra vários contextos limitados.

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.