Como usar análise de domínio para modelar microsserviços
Um dos maiores desafios de microsserviços é definir os limites de serviços individuais. A regra geral é que um serviço deve fazer "algo" – mas colocar essa regra em prática requer uma consideração cuidadosa. Não há nenhum processo mecânico que produz o design "certo". Você precisa pensar profundamente sobre seu domínio de negócios, requisitos, características de arquitetura (também conhecidos como requisitos não funcionais) e metas. Caso contrário, você pode terminar com um design aleatório que exibe algumas características indesejáveis, como dependências ocultas entre serviços, acoplamento rígido ou então interfaces mal projetadas. Este artigo mostra uma abordagem orientada por domínio para criar microsserviços. A avaliação dos limites de 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 de aplicativos adicionais para acomodar as alterações.
Este artigo usa um serviço de entrega por drones 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
Microsserviços devem ser criados em torno de capacidades comerciais, não de camadas horizontais como acesso a dados ou mensagens. Além disso, eles devem ter um acoplamento flexível e alta coesão funcional. Os microsserviços serão acoplados flexivelmente se você puder alterar um serviço sem a necessidade de outros serviços serem atualizados simultaneamente. Um microsserviço é coeso se ele tem uma finalidade única e bem definida, como gerenciar contas de usuário ou acompanhar o histórico de entrega. Um serviço deve encapsular o conhecimento do domínio e abstrair esse conhecimento de clientes. Por exemplo, um cliente deve ser capaz de agendar um zumbido sem conhecer 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.
O DDD (design orientado por domínio) fornece uma estrutura que pode ajudar você pela maior parte do processo de obtenção de um conjunto de microsserviços bem projetado. O DDD tem duas fases diferentes, a estratégica e a tática. No DDD estratégico, você está definindo a estrutura em grande escala do sistema. O DDD estratégico ajuda a garantir que sua arquitetura permaneça concentrada em capacidades comerciais. O DDD tático fornece um conjunto de padrões de design que você pode usar para criar o modelo de domínio. Esses padrões incluem entidades, agregações e serviços de domínio. Esses padrões táticos lhe ajudarão a criar microsserviços que são acoplados flexivelmente e coesos.
Neste artigo e no próximo, examinaremos as etapas a seguir, as aplicaremos ao aplicativo de Entrega por Drone:
Comece analisando o domínio empresarial para entender os requisitos funcionais do aplicativo. A saída desta etapa é uma descrição informal do domínio, que pode ser refinada em um conjunto mais formal de modelos de domínio.
Em seguida, defina os contextos limitados do domínio. Cada contexto limitado contém um modelo de domínio que representa um subdomínio específico do aplicativo maior.
Dentro de um contexto limitado, aplique padrões DDD táticos para definir entidades, agregações e serviços de domínio.
Use os resultados da etapa anterior para identificar os microsserviços em seu aplicativo.
Neste artigo, abordaremos as três primeiras etapas, que se relacionam principalmente com DDD. No próximo artigo, identificaremos os microsserviços. No entanto, é importante lembrar que DDD é um processo iterativo e em andamento. Limites de serviço não são fixos de forma imutável. Conforme um aplicativo evolui, você pode decidir dividir um serviço em vários serviços menores.
Observação
Este artigo não é destinado a mostrar uma análise de domínio completa e abrangente. Mantivemos o exemplo breve propositalmente para ilustrar os pontos principais. Para obter mais informações sobre DDD, recomendamos o livro Domain-Driven Design de Eric Evans, o livro que introduziu o termo pela primeira vez. Outra boa referência é Implementing Domain-Driven Design por Vaughn Vernon.
Cenário: Entrega por drone
A Fabrikam, Inc. está dando início a um serviço de entrega por drone. A empresa gerencia uma frota de aeronaves de tipo drone. Empresas se registram no serviço e os usuários podem solicitar que um drone colete mercadorias para entrega. Quando um cliente agenda uma coleta, um sistema de back-end atribui um drone ao usuário e notifica-o com um tempo de entrega previsto. Enquanto a entrega está em andamento, o cliente pode acompanhar a localização do drone, com um ETA atualizado continuamente.
Este cenário envolve um domínio bastante complicado. Algumas das preocupações de negócios incluem o agendamento drones, o acompanhamento de pacotes, o gerenciamento de contas de usuário e o armazenamento e análise de dados históricos. Além disso, Fabrikam deseja se lançar no mercado rapidamente e, em seguida, iterar rapidamente, adicionando novas funcionalidades e capacidades. O aplicativo deve operar em escala de nuvem, com um SLO (objetivo do nível de serviço) elevado. A Fabrikam também espera que diferentes partes do sistema tenham requisitos muito diferentes de armazenamento e consulta de dados. Todas essas considerações levam Fabrikam para escolher uma arquitetura de microsserviços para o aplicativo de Entrega por Drone.
Analisar o domínio
Usar uma abordagem DDD lhe ajudará a criar microsserviços de modo que cada serviço se adeque naturalmente a um requisito de negócios funcional. Ele pode lhe ajudar a evitar a armadilha de permitir que os limites organizacionais ou opções de tecnologia ditem o seu design.
Antes de gravar qualquer código, será necessária uma vista panorâmica do sistema que você está criando. O DDD começa modelando o domínio corporativo e criando uma modelo de domínio. O modelo de domínio é um modelo abstrato do domínio empresarial. Destila e organiza os dados de conhecimento do domínio e fornece uma linguagem comum para desenvolvedores e especialistas de domínio.
Comece mapeando todas as funções de negócios e as respectivas conexões. Isso provavelmente será um esforço colaborativo que envolve especialistas em domínio, arquitetos de software e outros stakeholders. Você não precisa usar nenhum formalismo específico. Esboce um diagrama ou desenhe em quadro de comunicações.
Conforme você preencher o diagrama, poderá começar a identificar subdomínios discretos. Quais funções estão intimamente relacionadas? Quais funções são fundamentais para os negócios e quais fornecem serviços auxiliares? O que é o grafo de dependência? Durante a fase inicial, você não se importa com tecnologias ou detalhes de implementação. Dito isso, você deverá tomar nota do local em que o aplicativo precisará se integrar com sistemas externos como CRM, processamento do pagamento ou sistemas de cobrança.
Exemplo: o aplicativo de entrega por drone
Após algumas análises de domínio iniciais, a equipe da Fabrikam criou um esboço aproximado que representa o domínio de Entrega por Drones.
- Envio é colocado no centro do diagrama, já que é essencial para os negócios. Tudo no diagrama existe para habilitar essa funcionalidade.
- Gerenciamento de drones também é importante para os negócios. Funcionalidades que estão intimamente relacionada ao gerenciamento de drones incluem o reparo de drones e o uso de análise preditiva para prever quando drones precisam de manutenção e reparo.
- A análise de ETA fornece estimativas de tempo para coleta e entrega.
- O transporte de terceiros permitirá que o aplicativo agende métodos de transporte alternativos se um pacote não puder ser enviado inteiramente por drone.
- Compartilhamento de drones é uma possível extensão do negócio principal. A empresa pode ter capacidade de drones excedente durante determinadas horas e pode alugar drones que, caso contrário, ficariam ociosos. Este recurso não estará na versão inicial.
- Vigilância por vídeo é outra área para a qual empresa pode expandir 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 momento no processo, não tomamos nenhuma decisão sobre implementação ou tecnologias. Alguns dos subsistemas podem envolver sistemas externos de software ou serviços de terceiros. Mesmo assim, o aplicativo deve interagir com esses sistemas e serviços, portanto, é importante incluí-los no modelo de domínio.
Observação
Quando um aplicativo depende de um sistema externo, há um risco de que a API ou o esquema de dados do sistema externo vaze dados para seu aplicativo, comprometendo consequentemente o design de arquitetura. Isso é especialmente verdadeiro com sistemas herdados que podem não seguir práticas recomendadas modernas e que podem usar esquemas de dados complicados ou APIs obsoletas. Nesse caso, é importante ter um limite bem definido entre esses sistemas externos e o aplicativo. Considere o uso do Padrão Estrangulador Fig ou o padrão Camada Anticorrupção para essa finalidade.
Definir contextos limitados
O modelo de domínio inclui representações de objetos reais no mundo – usuários, drones, pacotes e assim por diante. Mas isso não significa que todas as partes do sistema precisam usar as mesmas representações para as mesmas coisas.
Por exemplo, subsistemas que manipulam análise preditiva e reparo de drones 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. Porém, quando é hora de agendar uma entrega, esses elementos não importam. O subsistema de agendamento só precisa saber se um drone está disponível e o ETA para coleta e entrega.
Se tentássemos criar um único modelo para ambos esses subsistemas, ele seria desnecessariamente complexo. Também seria mais difícil para o modelo evoluir ao longo do tempo, porque as alterações precisariam atender a várias equipes trabalhando em subsistemas separados. Portanto, geralmente é melhor criar modelos separados que representam a mesma entidade do mundo real (nesse caso, um drone) em dois contextos diferentes. Cada modelo contém apenas os recursos e os atributos que são relevantes no contexto específico dele.
É aqui que o conceito DDD de contextos limitados entra em cena. Um contexto limitado é simplesmente o limite em um domínio em que um modelo de domínio específico se aplica. Examinando o diagrama anterior, é possível agrupar as funcionalidades dependendo de várias funções compartilharem ou não um único modelo de domínio.
Contextos limitados não são necessariamente isolados uns dos outros. Neste diagrama, as linhas sólidas, conectando os contextos limitados representam lugares onde dois contextos limitados interagem. Por exemplo, a Remessa depende de contas de usuário obterem informações sobre os clientes e do gerenciamento de drones 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 de 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 serviço de host aberto e linguagem de programação publicada. A ideia de serviço de host aberto é que um subsistema define um protocolo formal (API) para outros subsistemas se comunicarem com ele. A linguagem de programação publicada estende essa ideia publicando a API de uma forma que outras equipes podem usar para escrever código de clientes. No artigo Design de APIs para microsserviços, discutiremos o uso da especificação do OpenAPI (anteriormente conhecido como Swagger) para definir as descrições da interface independente de linguagem para APIs REST, expressa em formato JSON ou YAML.
Para o restante dessa jornada, nos concentraremos no contexto limitado de remessa.
Próximas etapas
Depois de concluir uma análise de domínio, o próximo passo é aplicar o DDD tático, para definir seus modelos de domínio com mais precisão.