Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DDD e Microsservicos - do negócio à arquitetura

468 views

Published on

O Domain Driven Design é um conjunto de princípios de construção de software baseado no profundo entendimento do negócio. Naturalmente, uma das áreas impactadas por esses princípios é a arquitetura. Em se tratando de Microsserviços, é ainda mais importante que a construção e organização dos serviços esteja alinhada com o negócio, para que se tenha o maior ganho de performance e eficiência na manutenção. Nessa apresentação discutiremos como modelar uma solução em Microsserviços utilizando conceitos do DDD.

Published in: Technology
  • Be the first to comment

DDD e Microsservicos - do negócio à arquitetura

  1. 1. Domain Driven Design • Filosofia de desenvolvimento definida por Eric Evans • Envolve o profundo entendimento do problema por meio de colaboração dos especialistas de negócio e especialistas técnicos • Conjunto de recomendações técnicas para construção de um design rico, que destaque o domínio do problema sem complexidades acidentais de implementação • Forma de pensar e agir em colaboração para construir uma solução escalável 5
  2. 2. Motivação Complexidade do domínio Complexidade técnica acidental Complexidade do software A origem do DDD está relacionada com os efeitos colaterais de decisões técnicas prematuras, enquanto o domínio de negócio ainda não está muito claro para o time. Um exemplo disso é a utilização de abstrações e patterns que não possuem relevância no momento atual do projeto. À medida em que o entendimento do domínio aumenta, a complexidade acidental do software também, quando as decisões técnicas acabam sendo limitadoras para a expansão veloz do software. 6
  3. 3. Especialista de negócios Analista de negócios Arquiteto DesenvolvedoresUsuários-chave Levantamento de requisitos Especificação funcional Desenho da arquitetura Software implementado Análise e desenvolvimento tradicional O modelo de análise e desenvolvimento tradicional estimula pouco contato direto entre o time de desenvolvimento e os especialistas de domínio. Papéis bem definidos caracterizam o fluxo de comunicação - os analistas de negócio participam do levantamento e especificação das necessidades do usuário, o arquiteto modela a solução de acordo com a especificação e da perspectiva dos analistas de negócios, e os desenvolvedores implementam o software de acordo com a arquitetura imposta e a especificação. Com esse distanciamento, o time que efetivamente irá implementar a solução muitas vezes não tem pleno entendimento do domínio, nem pode contribuir tecnicamente com a solução mais adequada para resolver o problema do usuário. 7
  4. 4. O Design Direcionado ao Domínio estimula a comunicação direta entre os especialistas de domínio, analistas de negócio e time técnico. As decisões arquiteturais são responsabilidade do time técnico como um todo, incentivando a refatoração do design e da implementação à medida que o entendimento do domínio aumenta. A implementação visa refletir o domínio especificado - se você extrair um diagrama de classes e/ou sequência a partir dos softwares que trabalha hoje, estes seriam facilmente compreendidos pelo usuário, com os mesmos termos e fluxos que eles usam no dia a dia?
  5. 5. Nossa empresa comercializa Produtos sob demanda. Precisamos de um software que gerencie a produção a partir de um Pedido de Venda. O Pedido de Venda pode conter vários Produtos, compostos por vários Componentes. Quando um Pedido de Venda é emitido, é necessário verificar a disponibilidade dos Componentes do Produto. É feita a reserva dos Componentes disponíveis, e emissão de Pedidos de Compra para os indisponíveis. Há um sistema legado que gerencia a entrada e saída de Componentes no Estoque, que pode ser integrado para notificar a chegada dos Componentes solicitados. Quando todos os Componentes estiverem disponíveis, é emitida a Ordem de Serviço. Após a finalização da produção, outros processos podem ser iniciados, como emissão de Nota Fiscal. EXEMPLO Imaginem o case descrito nesse slide. Uma empresa que produz equipamentos sob demanda deseja um novo módulo de gerenciamento de produção que se integre a um sistema de estoque legado. Como seu time realizaria a destilação o modelagem do domínio? 9
  6. 6. Perspectiva dos substantivos Nossa empresa comercializa Produtos sob demanda. Precisamos de um software que gerencie a produção a partir de um Pedido de Venda. O Pedido de Venda pode conter vários Produtos, compostos por vários Componentes. Quando um Pedido de Venda é emitido, é necessário verificar a disponibilidade dos Componentes do Produto. É feita a reserva dos Componentes disponíveis, e emissão de Pedidos de Compra para os indisponíveis. Há um sistema legado que gerencia a entrada e saída de Componentes no Estoque, que pode ser integrado para notificar a chegada dos Componentes solicitados. Quando todos os Componentes estiverem disponíveis, é emitida a Ordem de Serviço. Após a finalização da produção, outros processos podem ser iniciados, como emissão de Nota Fiscal. Em um modelo tradicional de especificação de software, são destacados os substantivos e a relação entre eles. Com isso é possível desenhar um MER - Modelo de Entidade e Relacionamento, e iniciar a construção do software. 10
  7. 7. Perspectiva dos verbos Nossa empresa comercializa Produtos sob demanda. Precisamos de um software que gerencie a produção a partir de um Pedido de Venda. O Pedido de Venda pode conter vários Produtos, compostos por vários Componentes. Quando um Pedido de Venda é emitido, é necessário verificar a disponibilidade dos Componentes do Produto. É feita a reserva dos Componentes disponíveis, e emissão de Pedidos de Compra para os indisponíveis. Há um sistema legado que gerencia a entrada e saída de Componentes no Estoque, que pode ser integrado para notificar a chegada dos Componentes solicitados. Quando todos os Componentes estiverem disponíveis, é emitida a Ordem de Serviço. Após a finalização da produção, outros processos podem ser iniciados, como emissão de Nota Fiscal. Porém a maioria dos softwares não são meros repositórios de dados. O objetivo é solucionar algum problema real, e utilizar dados como apoio à essa solução. No DDD destacam-se os verbos, ou seja, as ações e eventos que devem ocorrer na solução. 11
  8. 8. Building Blocks Fábricas Objetos de valor Serviços Módulos Entidades Eventos de domínio Interfaces reveladoras de intenções Repositórios Trackeamento de eventos Agregados Os Building Blocks são conceitos de implementação que podem ser utilizados para implementar um domínio rico e coeso. Não são criações originais do Eric Evans, fundador do DDD, são patterns e conceitos muito utilizados no mercado que foram selecionadas por ele para exemplificar a implementação de software com o mindset do DDD. 12
  9. 9. Modelo de domínio • Objetos de valor: Item de Pedido de Compra, Item de Pedido de Venda • Entidades: Produto, Componente • Agregados: Pedido de Compra, Pedido de Venda • Serviços: Emissão de Pedido de Venda, Emissão de Pedido de Compra • Eventos de domínio: Chegada de componentes no estoque De acordo com o case que mencionamos, os objetos poderiam ser classificados em building blocks dessa forma. 13
  10. 10. Domínio Produção e comércio de equipamentos sob demanda Durante o processo de destilação do domínio, inicialmente temos uma visão geral da necessidade de negócio. 14
  11. 11. Subdomínios Com as interações, é possível "quebrar" o domínio inicial em domínios menores dentro de sub-contextos de negócio... 15
  12. 12. Domínio principal, genérico e auxiliar ...para então classificá-los em domínios principais (o core do negócio, o diferencial que a empresa oferece), auxiliares (suporte aos domínios principais) e domínios genéricos (que poderia ser adquirido com um software de prateleira). 16
  13. 13. Uma das recomendações do Evans é não investir em documentação extensa de software. Porém um diagrama que ele não abre mão é o Mapa de Contexto. Ele mostra a relação entre domínios e a forma de comunicação entre eles. No exemplo acima há a separação etre desenvolvimento interno e externo (terceirizado ou produto fechado de mercado). Os módulos de Produção e Cadastros compartilham uma biblioteca de gestão de autenticação e permissões (Núcleo Compartilhado). O módulo de produção consome o módulo de controle de estoque por meio de um conjunto de adaptadores que "traduzem" os objetos e chamadas de um módulo para o outro sem trazer os vícios e débitos técnicos do projeto legado para o novo (Camada Anticorrupção). A empresa optou por contratar uma solução customizada de Vendas, em que é possivel solicitor alterações (Cliente - Fornecedor). Esta solução consome uma API de Emissão de NFe do governo (Linguagem Publicada). Também foi adquirida uma solução de Mercado para compras, porém esta não oferece suporte ou customizações, então as adaptações devem ser feitas do lado consumidor no módulo de produção (Conformista). A tendência é que se crie uma camada anticorrupção nesses casos.
  14. 14. É importante ressaltar que cada módulo pode ser desenvolvido da forma mais conveniente à natureza do sub-domínio que se refere, tanto no ponto de vista de design, quanto de tecnologia, e até mesmo time/ pessoas envolvidas. O módulo de cadastros pode ter um design simples característico de operações CRUD. O banco pode ser relacional, e o time, mais iniciante, por exemplo. O módulo de controle de estoque, por ser um projeto legado, possui complexidades que não precisam ser refatoradas imediatamente. O módulo novo de gerenciamento de produção, que é o core do negócio, pode possuir um design mais robusto segundo as práticas e princípios do DDD, talvez com um banco de dados não relacional, e com um time mais experiente e especialista.
  15. 15. Com os fundamentos do DDD em mente, como podemos aplicar esses princípios na modelagem de Microsserviços para nos beneficiarmos com as vantagens de ambas as abordagens?
  16. 16. A arquitetura de “Microsserviços” não tem um fundador oficial. Convencionou-se como uma especialização de arquitetura distribuída, em que serviços independentes se comunicam via interfaces agnósticas à tecnologia. Por “independente” entenda: ciclo de vida individual e resiliente, em que um serviço pode ser deployado ou desligado sem impacto na solução. O termo “micro” é controverso. Não existe uma definição acadêmica do quão pequeno é um microsserviço, quantas classes ou linhas de código. Faz mais sentido pensar que é um serviço que atende a um único propósito. A proposta é prover gerenciamento descentralizado ao contexto de negócio. Determinado contexto pode demandar necessidades específicas, tanto no desenvolvimento (linguagem, paradigma) quanto na infra (bare metal vs virtualização, número de instâncias). Quando o modelo está maduro, permite entregas velozes, ambiente resiliente e elasticidade.
  17. 17. A falha na implantação dos princípios básicos pode transformar o que seria uma solução de microsserviços em um monolito de composto em serviços altamente acoplados - na prática, o que antes era um ponto de falha centralizado e um serviço para versionar, deployar e sustentar, se transforma em dezenas ou centenas.
  18. 18. Quando a solução envolve centenas de serviços, é praticamente impossível realizar testes end-to-end em um ambiente local. Porém é possível ter confiança nas entregas se os contratos de comunicação estabelecidos estiverem bem validados. A utilização de mocks viabiliza a automação dos testes de integração. Os testes de aceitação podem consumir bases de dados descartáveis para que possam ser executados a qualquer momento sem prejudicar a massa de dados de testes funcionais em andamento. O desenvolvimento de serviços deve visar a compatibilidade - se houver quebra de contrato, a versão nova deve coexistir com a antiga até que todos os serviços que a consomem estejam utilizando a versão nova. Com isso estratégias de deploy Blue / Green podem ser implementadas - a versão nova entra em produção, é validada, só então o tráfego é redirecionado gradualmente da versão anterior para a nova, até que a versão anterior possa ser desativada.
  19. 19. Segundo a Conway’s Law -“Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure”, isto é, a implementação da solução reflete a estrutura empresarial, o que muitas vezes não é o mais adequado para tirar proveito da flexibilidade que a arquitetura de microsserviços oferece. Se isso acontecer, pode-se imaginar que a organização dos microsserviços irá refletir a organização dos times, por exemplo, front-end, regras de negócios, infraestrutura, etc.
  20. 20. Ao invés disso, os princípios do DDD podem ser considerados para aproximar a implementação da natureza do negócio. Um contexto pode demandar uma tecnologia que o atenda melhor, como uma linguagem de programação, modelo de banco de dados (no-sql / relacional) ou de infraestrutura (baremetal / virtualização). Com limites bem delimitados, a melhor forma de conectá-los e gerenciar sua comunicação pode ser identificada e implementada.
  21. 21. Durante o desenvolvimento de aplicações monolíticas, a preocupação com a latência de operações é baixa. É esperado que a performance da aplicação de uma forma geral seja ainda melhor em produção, por ser um ambiente mais robusto por natureza. Porém com microsserviços, o processamento de uma única transação pode passar por dezenas de serviços até que seja concluída. Quando os times não estão levam isso em consideração durante o desenvolvimento, falhas de performance e disponibilidade só serão identificadas em produção. Algumas das asserções mais ingênuas que programadores que não estão acostumados com microsserviços pensam foram compiladas no "Fallacies of distributed computing" http://nighthacks.com/jag/res/Fallacies.html
  22. 22. A Netflix tem uma abordagem interessante para zelar pela resiliência da solução sem interferir na liberdade de desenvolvimento dos times - “The Freedom and Responsibility culture at Netflix doesn’t have a mechanism to force engineers to architect their code in any specific way.” Para que todos os times desenvolvessem serviços visando a resiliência, foi instituído primeiramente o Chaos Monkey, procedimento que desativava clusters aleatoriamente, depois o Chaos Kong, que desativava datacenters, para validar a geo-redundância da solução. Outras iniciativas implantadas foram o FIT (Failure Injection Testing) e o ChAP (Chaos Automation Platform) para injetar falhas diretamente em serviços. Todas essas ações resumem uma espécie de “Chaos-driven development” - falhas acontecem, e a solução e o time precisam estar preparados para isso.
  23. 23. Para mostrar o processo de modelagem com o mindset do DDD, vamos imaginar um cenário em que um modulo de uma aplicação monolítica possui uma demanda diferenciada, e a empresa optou por isolá-lo para gerenciar seu ciclo de vida de forma mais adequada. A aplicação é um portal de troca de pontos por produtos, semelhante a um e-commerce.
  24. 24. O fluxo da transação de resgate de pontos pode ser descrito com o processo acima. 28
  25. 25. Os sistemas e tecnologias envolvidos pode ser descrito conforme o diagrama acima. A API de Carrinho de compras é uma solução monolítica. Após a transação ser finalizada, o fluxo de logística com uma API Externa é iniciado, e o usuário será notificado posteriormente por email com a confirmação da data da entrega. 29
  26. 26. Uma forma de organizar os components da API do Carrinho de compras é demonstrada acima. 30
  27. 27. Um exemplo em .NET da implementação da API é demonstrada acima. 31
  28. 28. Diferentemente do que se fala no mercado, a abordagem monolítica não é necessariamente ruim. Muitas vezes é associada às desvantagens de projetos legados e débitos técnicos, porém quando bem implementada possui diversas vantagens para um cenário em que a solução realmente pode ser vista como uma unidade. 32
  29. 29. Ao isolar o módulo de estoque, há a alteração ou remoção de diversos componentes dentro da API de Compras. 33
  30. 30. Será necessário decidir como os sistemas lidarão com o código compartilhado - normalmente de infra estrutura ou o famoso "utils" - funcionalidades genéricas que foram abstraídas de forma a serem reaproveitadas e aumentar a velocidade no desenvolvimento. A primeira opção é duplicar esses códigos no serviço novo que contemplará o módulo de estoque. A segunda, utilizada nesse exemplo, é isolar o código compartilhado em bibliotecas e distribuí-las em ambos os serviços. 34
  31. 31. Há cenários em que é mais simples duplicar o código, quando aquela funcionalidade pode crescer com velocidades e necessidades diferentes entre os consumidores. E há cenários em que o Código compartilhado deveria ser distribuído via serviço, e não como componente - se a funcionalidade deve estar 100% atualizada para todos os consumidores em tempo real, como o que ocorre com regras de negócio, por exemplo. Caso contrário, atualizar o componente implica no redeploy de todos os consumidores. 35
  32. 32. Após o isolamento do modulo de infra e adaptações na API de Carrinho de Compras, é feito o isolamento do modulo de estoque e também do seu banco de dados. Nesse contexto, a API de Estoque é exposta internamente no cluster, ao invés de ser exposta publicamente como a API do Carrinho de Compras. 36
  33. 33. Na API de Estoque ficam só os components relevantes ao sub-domínio de estoque. 37
  34. 34. Na API de Carrinho de Compras, parte do código de estoque foi removida, porém alguns componentes continuam - por exemplo o serviço de estoque, que ao invés da implementação concreta será um adapter de comunicação com a nova API de Estoque. A entidade Produto continua existindo, porém apenas com o conteúdo relevante para esse contexto. 38
  35. 35. A transação de resgate de pontos depende que os produtos sejam reservados no estoque para que seja concluída. O usuário está aguardando a conclusão da transação com seu número de protocolo e espera que isso aconteça em poucos instantes. O que acontece quando a comunicação com o serviço de Estoque falha, seja por bug ou por problemas de conexão (timeout, permissões de rede, etc)? Falhas de compatibilidade não são mais percebidas em tempo de compilação! Caso algum problema ocorra, o rollback lógico deve ser realizado, provavelmente com uma estratégia SAGA cuja implementação não introduza mais pontos de falha - no momento temos um risco, que é a disponibilidade, comunicação e funcionamento do serviço de estoque - se incluirmos outro serviço REST para orquestrar essa comunicação, teremos dois riscos! Outra abordagem, como a associação entre os componentes da transação com o número de protocolo, caso o protocolo não seja confirmado após 30min, o saldo é extornado e a reserve de produtos é cancelada, pode ser uma solução mais confiável. 39
  36. 36. 41
  37. 37. 42

×