Boas-vindas ao curso de arquiteturas modernas e escaláveis em .NET. Eu sou Daniel Portugal, instrutor e desenvolvedor do .NET.
Audiodescrição: Daniel é um homem branco, de cabelos pretos e barba. Ele usa óculos e tem olhos castanhos. Está vestindo uma camisa laranja e, ao fundo, há detalhes em azul e um armário.
Para acompanhar este curso de forma tranquila, é necessário ter alguns conhecimentos prévios. O primeiro é entender sobre Docker e Containers. Além disso, é importante conhecer o desenvolvimento de aplicações web, principalmente APIs, utilizando o AspNet Core. Embora não desenvolvamos ou escrevamos muito código aqui, passaremos por várias partes do nosso código e bibliotecas que utilizamos, então esse conhecimento é essencial.
Outro ponto interessante que abordaremos é o Domain Driven Design, que é uma maneira de separar uma aplicação monolítica em uma arquitetura distribuída com microserviços. Não é necessário um conhecimento profundo, mas mencionaremos esses nomes e padrões, então é bom ter uma noção sobre o assunto. E, claro, é necessário conhecimento em C#, orientação a objetos e a capacidade de rodar aplicações no .NET, utilizando os comandos .NET. Esses são os pré-requisitos para acompanhar o curso.
O que vamos aprender exatamente neste curso? Vamos transitar de uma arquitetura monolítica para uma arquitetura de microserviços. Discutiremos as principais complexidades que enfrentamos como pessoas desenvolvedoras ao lidar com esse tipo de arquitetura. Com vários serviços rodando, diversas dependências, imagens Docker, banco de dados e mensageria, como lidamos com essas complexidades? Trabalharemos em soluções para esses problemas.
Quais são esses problemas? Como fazemos para os serviços se comunicarem? Como um serviço busca informações de outro de forma síncrona? Ou como um serviço envia eventos e mensagens para outro serviço? Como realizamos essa comunicação? Outro problema é como tornar esses serviços facilmente descobertos em uma rede para que outros clientes possam consumir essa API. Vamos trabalhar com uma API, então a descoberta de serviços é fundamental. Como colocamos proteção nessa arquitetura distribuída? Onde devemos implementar essa proteção? Esses são alguns dos problemas que precisamos resolver dentro dessa arquitetura distribuída.
Um outro problema que já está mais relacionado ao processo de desenvolvimento, do time de desenvolvimento, é a gestão de várias aplicações rodando para apresentar toda a solução, toda a API que vamos disponibilizar. Como lidamos com esse conjunto de aplicações em execução? E como evitamos a necessidade de subir manualmente as imagens necessárias para rodar as APIs? Por exemplo, subir uma imagem do SQL Server ou de um provedor de identidade. Como fazemos isso para tornar o processo de desenvolvimento mais fluido? Vamos trabalhar bastante com isso também.
Outra complexidade importante, e fundamental no curso, é pegar essa solução distribuída e disponibilizá-la em um ambiente operacional. Qual é o padrão de mercado para fazer isso? Como fazemos isso? E, após colocarmos essa solução em um ambiente operacional, como monitoramos? Como observamos essas informações? Como diagnosticamos um erro, verificamos problemas de performance e realizamos otimizações? Esses são os itens que vamos trabalhar, principalmente como lidar com a complexidade de uma arquitetura distribuída.
Vamos discutir as soluções para isso. Abordaremos mensageria e comunicação síncrona, utilizando uma biblioteca chamada Refit. Implementaremos um gateway usando o YARP, uma solução específica para isso. Também implementaremos a segurança com o Keycloak. Transformaremos nosso ambiente de desenvolvimento de um processo individual para um processo uniforme usando o Aspire. Em seguida, implementaremos essa solução operacional usando o Kubernetes e um gerenciador de pacotes chamado Helm. Por fim, aplicaremos observabilidade e monitoramento com uma solução da Microsoft chamada Aspire Dashboard. Tudo isso será feito de forma prática.
Utilizaremos um projeto que é uma API da Volmed. A Volmed é uma empresa que trabalha com sistemas de saúde e agendamento de consultas. Para isso, é necessário ter uma base de pacientes, uma base de médicos e bastante disponibilidade para a parte de agendamento, pois essa função é crítica. Pessoas doentes precisam de atendimento emergencial e de agendar consultas. Vamos lidar com isso também, tudo com a API da Volmed.
Então, é isso. Nos vemos no próximo vídeo, onde começaremos a explorar todos esses assuntos na prática. Até lá.
Vamos conhecer o projeto com o qual trabalharemos neste curso. Solicitamos que baixem em suas máquinas a solução que temos aberta no Visual Studio e faremos uma visão geral dessa solução.
A solução está organizada em dois projetos. O projeto médicos.service.api é o foco do nosso curso. Há outro projeto chamado Vomad Web, que é uma interface web que consome essa API. Não trabalharemos com esse projeto, mas ele demonstra que existe uma aplicação cliente que consome essa API. Outras aplicações clientes, como aplicações desktop e mobile, também podem consumir a mesma API. Nós, como pessoas desenvolvedoras da Vomad, daremos manutenção na API médicos.service.api.
Para executar essa API, no Visual Studio, utilizamos o botão verde ou o atalho Ctrl + F5, garantindo que o projeto médicos.service.api esteja marcado como inicialização. Ao clicar no triângulo verde, apenas a API será executada. Isso abrirá uma janela do terminal, onde alguns comandos SQL serão executados para migração e inclusão automática de registros. Este não é um projeto para produção, mas deixamos assim para termos dados com os quais trabalhar.
Além da janela do terminal, uma janela no navegador será aberta com a documentação da API, a famosa página do Swagger. Essa página mostra os recursos que a API está expondo: consulta, médico e paciente. Esses recursos representam as funcionalidades que a Vomad está mantendo atualmente.
O recurso de consulta permite que pessoas atendentes e pacientes realizem agendamentos. Há um post para salvar consultas, onde se aloca um médico de uma especialidade a um paciente em um horário específico. É possível consultar, alterar, excluir ou cancelar agendamentos.
Também temos a gestão de médicos, onde podemos incluir novos médicos, alterar informações cadastrais, e o mesmo se aplica a pacientes. Podemos alterar dados cadastrais, como e-mail, endereço e celular, além de mudar o contato do paciente.
Um endpoint importante é o de importação de pacientes em lote. Um dos objetivos do negócio Vomad é aumentar a base de pacientes para alocá-los aos médicos através das consultas. Quanto mais pacientes, melhor para o negócio, indicando crescimento. O post de importação em lote simula essa funcionalidade, permitindo importar pacientes fictícios. Ao executar, ele responde com sucesso, indicando a importação de pacientes.
Imaginemos que essa API serve diversos clientes. Mostramos a interface web, mas podemos ter vários tipos de clientes. Por exemplo, uma interface no consultório médico para agendar consultas de pacientes que chegam, às vezes com emergência. A pessoa atendente consulta a agenda do médico para alocar um horário.
Simultaneamente, um usuário administrativo ou de suporte pode usar a mesma API para incluir pacientes em lotes. Vamos simular essas duas operações em conjunto para observar o que pode ocorrer nesse cenário comum.
Abriremos mais uma aba com a página do Swagger para simular as duas operações simultaneamente. De um lado, faremos a consulta, e do outro, a importação em lote de pacientes. Ao executar, a pessoa do suporte importa o arquivo no endpoint de importação, enquanto a atendente verifica a consulta do médico. Notamos que a verificação de agendamento só retorna o resultado após a conclusão da importação em lote, causando demora na resposta.
Vamos simular uma importação maior, com 5 mil pacientes, e observar que a atendente continua esperando. Existe um impacto entre o endpoint de importação de pacientes e a consulta de agendamentos de médicos, um influenciando o outro. Queremos trazer essa discussão e reflexão sobre o que está acontecendo. Nossa API fornece três recursos: consultas, médicos e pacientes.
O problema que demonstramos, um problema comum de lock no banco de dados, ocorre devido ao forte acoplamento entre três recursos distintos do negócio. Essas partes têm características diferentes: consultas precisam estar disponíveis 24 horas por dia, 7 dias por semana, devido à necessidade de agendar pacientes em emergências, enquanto a parte de pacientes e médicos não é tão crítica. É importante destacar essa diferença. No entanto, existe um forte acoplamento entre esses três componentes ou módulos.
Isso acontece porque temos uma arquitetura monolítica, que junta todas essas partes em uma única aplicação. Essa mistura pode gerar código desorganizado, com referências desnecessárias entre áreas específicas do código. As funções de negócio estão misturadas em uma única aplicação e um único banco de dados, o que causa problemas de travamento. Embora essa abordagem ofereça simplicidade e integridade referencial, ela também traz acoplamento entre tabelas e estruturas.
A arquitetura monolítica apresenta várias limitações. Uma delas é o autoacoplamento, que pode causar impacto em diferentes partes do sistema, como o lock que ocorreu. Além disso, ao modificar o código, podemos introduzir defeitos em outras áreas se o código não estiver bem organizado. Outras limitações incluem a dificuldade de escalar a aplicação, já que é um único executável. Se as consultas aumentarem, precisamos escalar também para médicos e pacientes.
O deploy possui alto risco, pois uma atualização em uma funcionalidade pode causar indisponibilidade em outra parte do sistema. As atualizações são complexas, pois a parte de consultas, que é crítica, precisa estar sempre atualizada, enquanto pacientes e médicos podem atrasar essa atualização. Além disso, há uma dificuldade organizacional em dividir a aplicação em times funcionais independentes, pois a comunicação entre eles precisa ser mantida.
Essas limitações impactam a agilidade do negócio em implementar decisões estratégicas. A arquitetura monolítica pode ser comparada a um grande cargueiro, eficiente e simples, mas lento para mudanças de rota e sujeito a bloqueios em caso de problemas. A alternativa é uma frota de lanchas pequenas e rápidas, que representam a arquitetura de micro-serviços. Essa abordagem divide a solução em componentes menores e autônomos, permitindo maior agilidade e resiliência.
Chris Richardson, em seu livro, fala sobre o triângulo do sucesso, que inclui arquitetura, processo e organização. A arquitetura de micro-serviços habilita um design organizacional com times interdependentes e um processo mais ágil, resultando em uma entrega de valor rápida, frequente e confiável.
O objetivo não é convencer a adotar exclusivamente micro-serviços, mas sim perceber o equilíbrio e tomar decisões importantes para o projeto. A arquitetura de micro-serviços oferece agilidade, mas com maior complexidade de comunicação. Já o monolito garante eficiência e simplicidade, mas pode ser lento para implementar decisões estratégicas. É importante entender qual arquitetura se adequa melhor ao processo.
No próximo passo, vamos discutir uma arquitetura de micro-serviços para a Avonmed. Nos vemos lá.
Mostramos a solução monolítica da Novomedia, na qual tínhamos uma API única com um banco de dados único. Apresentamos as limitações dessa arquitetura, destacando que, em última instância, ela diminui a agilidade na implementação de decisões estratégicas do negócio. Em seguida, apresentamos uma alternativa: a arquitetura de micro-serviços, comparando-a a uma frota de lanchas.
A partir de agora, vamos trabalhar com uma nova solução no Visual Studio, que começa a implementar uma arquitetura de micro-serviços. Neste curso, não discutiremos o processo de transição de um monolito para um micro-serviço. O foco será nas grandes complexidades que enfrentamos ao trabalhar com uma arquitetura de micro-serviços. Partiremos de uma solução já separada em micro-serviços e mostraremos no Visual Studio como essa separação foi feita.
Farei um zoom para mostrar novamente o gerenciador de soluções, que agora está diferente. Temos três projetos que são APIs, separados por recursos, como se fossem subdomínios do DDD (Domain Driven Design). Em um curso, discutimos o que são subdomínios, e deixarei como referência para quem quiser estudar mais. Os projetos são: consultas, médicos e pacientes, cada um implementando e expondo esses recursos em uma API AspNetCore.
Além disso, temos outro projeto chamado Vomed Shared Pagination, que é um dos padrões de comunicação que o DDD sugere entre subdomínios, conhecido como Shared Kernel. Esse padrão é utilizado quando há uma solução comum a todos os contextos, e queremos trazê-la para um projeto único. Embora haja um forte acoplamento, neste caso, trata-se de uma solução de paginação que dificilmente mudará ao longo do tempo. Assim, todos os projetos de consultas, médicos e pacientes fazem referência a esse projeto de paginação.
Uma das primeiras complexidades que enfrentamos com essa arquitetura de micro-serviços é a execução dos serviços. Não temos mais uma aplicação única para executar; precisamos executar os três serviços. Se quisermos testar especificamente um serviço, podemos executar apenas um deles. No entanto, neste caso, queremos mostrar toda a API de uma vez, então precisamos executar os três serviços simultaneamente no Visual Studio.
Percebam que, inicialmente, não conseguimos saber o que será executado. Precisamos selecionar o item desejado. Ao clicar na seta apontando para baixo, temos a possibilidade de selecionar consultas, médicos, pacientes, e até mesmo a web, embora não trabalhemos com web neste contexto. Podemos executar esses três individualmente, mas o Visual Studio oferece uma funcionalidade interessante: a criação de um profile de inicialização, que permite agrupar vários projetos para serem executados de uma vez só.
Vamos realizar o seguinte procedimento: sairemos do zoom, clicaremos na seta e, em seguida, no menu chamado "configurar projeto de inicialização". Ao fazer isso, uma janela será exibida. Nesta janela, já realizamos alguns testes, então clicaremos no item "vários projetos de inicialização".
Dentro dessa lista chamada "serviços", nomeamos um perfil. É possível criar vários perfis aqui. Podemos criar um novo perfil, renomeá-lo e dar o nome desejado, como "serviços 2", por exemplo. Este é um novo perfil de inicialização, no qual podemos definir a execução de médicos e pacientes. Neste caso, não faremos isso, então clicaremos em "serviços 2" e apagaremos esse perfil. Podemos ter todos os serviços executando, mas criamos um perfil de inicialização chamado "serviços".
O que esse perfil faz? Na parte direita, temos todos os projetos da solução listados, e definiremos a ação a ser realizada: inicializar médicos, pacientes e consultas. Há uma coluna chamada "destino de depuração", que são os launch profiles dentro de cada projeto na parte de propriedades. Aqui, definimos o destino, ou seja, o perfil que será executado para iniciar. Com esse perfil de inicialização, podemos definir a execução conjunta dos três serviços.
Clicaremos no triângulo verde vazado para executar esse perfil de inicialização, o que significa que três janelas do terminal e três abas do navegador serão abertas. Observem as três janelas do terminal: uma, duas, três. Saímos de um executável único para três executáveis, um para cada tipo de serviço.
Ao mesmo tempo, temos agora uma complexidade adicional: três janelas do navegador, cada uma com a documentação do seu recurso. Este é o início de uma arquitetura de microserviços, que utilizamos para separar subdomínios do nosso negócio. A parte de consultas, pacientes e médicos, cada uma se tornou um serviço, um executável.
Vamos testar novamente o processo de importação de pacientes com consultas. Clicaremos em "importação de pacientes" e definiremos que queremos importar. A interface mudou, agora é um endpoint, uma API mais voltada para a arquitetura RESTful, onde o próprio verbo indica o tipo de operação que estamos realizando, diferente da arquitetura inicial do monolito.
Aqui, queremos executar a importação de cinco mil pacientes. Vamos executar e deixar o processo em andamento. No entanto, continuamos com o mesmo problema: o médico João Silva ainda aparece. Houve um pequeno atraso, e a pessoa atendente continua enfrentando esse problema. Imagino que já saibamos a resposta, e discutiremos essa resposta no próximo vídeo.
O curso Arquitetura distribuída e escalável com .NET: do monolito ao Kubernetes possui 349 minutos de vídeos, em um total de 59 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Matricule-se no plano PLUS e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Mobile, Programação, Front-end, DevOps, UX & Design, Marketing Digital, Data Science, Inovação & Gestão, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para estudantes ultra comprometidos atingirem seu objetivo mais rápido.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.