Vamos aí ao nosso SOS monolito, como tunar e recuperar um sistema monolítico. Eu vou deixar aqui o chat aberto, caso vocês queiram interromper, fazer alguma pergunta, alguma coisa assim, tá? Esteja à vontade, não precisa esperar o final da apresentação, porque como a gente está em um grupo mais fechado aqui, fica mais até bacana de responder em vez de responder lá no final. Show de bola. Então, para quem não me conhece, meu nome é Luiz Carlos, está aí na tela, bem categórico. Hoje eu sou CTO aqui no Full Cycle e também estou junto com Wesley e mais todos os tutores que fazem parte da Full Cycle, à frente dos treinamentos, pós-graduação e cursos e etc. Na verdade, quando eu entrei para poder trabalhar com Wesley, eu era desenvolvedor. O meu grande background vem de desenvolver aplicações principalmente para web e prestação de consultoria. principalmente para web e prestação de consultoria. Eu já ajudei muitas empresas também, e eu vou falar um pouco disso no decorrer da apresentação, já ajudei muitas empresas a fazer essa gestão técnica de projetos internos ou fazer recuperações dele. Eu já vi muitos problemas e... Vacinei muitas empresas a não tomarem decisões erradas e provavelmente vocês devem se identificar. Falar um pouco de mim, eu fiz sistema de informação na PUC, sou MVP Microsoft, Docker Captain, se tiverem que entrar em contato comigo nas redes sociais, só procurar a Argentina Luiz por qualquer rede social. Primeiro, vamos falar um pouquinho sobre ciladas, né, ao lidar com monolitos. E dessas ciladas aqui, nós até tentamos quase destruir o nosso monolito quando o assunto é um determinado questão, não vou adiantar, mas vamos falar que é a primeira parte, né? Se vocês se identificarem, podem mandar aí no chat. Ah, se eu tenho um monolito com um problema, qual que é a primeira decisão que eu vou resolver? Vamos criar microserviços. É, um meme categórico. A gente tem que lembrar que microserviços é uma decisão primeiro de negócio. Ela não foi criada para poder resolver A gente tem que lembrar que microserviços é uma decisão primeiro de negócio, ela não foi criada para poder resolver questões técnicas, é porque empresas que têm muitos desenvolvedores acabam tendo conflitos em cima ali do mesmo projeto, então você consegue alocar melhor as squads e ter uma independência maior na sobrevida dessas aplicações. Então, primeiro, é uma decisão política da empresa, depois acaba se tornando um benefício técnico, que aí, enfim, não é o assunto aqui dessa apresentação. Deixa eu só fazer uma coisinha aqui, pessoal, para melhorar essa apresentação aqui. Onde que eu vou aqui numa configuração acho que é mais aqui tem que desabilitar as anotações porque às vezes o pessoal anota aqui segunda cilada, a gente está vendo esse meme revisitado de várias formas, vamos criar do zero talvez esse aqui Segunda cilada, a gente está vendo esse meme revisitado de várias formas. Vamos criar do zero. Talvez esse aqui, junto com o de microserviços, são os dois erros primordiais. Porque aí você tem um monolito ali, vamos criar aqui com a última linguagem de programação, com o framework X. O problema do seu monolito, se ele está realmente difícil de refatorar, de criar novas funcionalidades, de manter essa coisa, o problema não é criar do zero. Você vai criar do zero, uma aplicação ali da primeira versão vai ficar até legal, ela vai funcionar, mas vai cair nos mesmos erros de novo. É a mesma coisa da gente não entender o que está acontecendo, vai cair nos mesmos erros de novo. É a mesma coisa da gente não entender o que está acontecendo, pegar toda a sujeira, abrir o tapete e dar uns tapinhas em cima. Tá? Criar do zero pode ser uma solução, mas quando se fala isso, é a mesma coisa de você estar falando, ah, meu computador está com vírus, vou formatar minha máquina. Isso deveria ser a última decisão que você vai tomar, ou deveria ser uma decisão consciente. Uma outra cilada muito comum também é só escalar verticalmente ou horizontalmente. Eu tenho meu monolito ali que está com problemas de CPU e memória. Manda ver com o cloud o quanto que isso vai custar. Porque você pode... isso aqui às vezes é um paliativo, mas o quanto que isso vai custar para a empresa, o quanto tempo que isso vai rodar? É porque você está jogando literalmente dinheiro fora, se você está só escalando, sem de fato conseguir fazer o que é necessário. Outra cilada, só usar cache. Ah não, tem uma consulta ali que está lenta, alguma parte da aplicação que não está atendendo as solicitações, se eu não tacar o quê? Redis, não é assim que funciona? Eu não sei por que criaram esse mito do Redis como solucionador de problemas. Às vezes, o uso desse cache pode custar mais caro e não resolver o problema, e você ter... gastar mais tempo para devolver a resposta, e aí complica-se mais a arquitetura da aplicação ainda. Então, cuidado para esses quatro pontos que nós estamos falando. Mas aí vem a questão que eu já recebi muito na minha carreira, ao longo das consultorias que eu prestei, e também nessa área educacional, eu recebo muito essas dúvidas de empresas e de alunos. Minha aplicação está lenta como resolver? Isso aqui já denota um problema porque quando você faz essa questão, você não sabe o que está acontecendo com a sua aplicação. E você está querendo uma resposta mágica, que alguém tenha uma receita de bolo, uma solução assim, faz um estralo de dedos e aí pronto. Não, não tem como saber. São tantas variáveis envolvidas que podem estar fazendo o seu monolito, não atender as solicitações, estar consumindo muitos recursos, estar difícil de refatorar, que somente uma análise mais ponderada vai ter essa resposta. Então, não tem uma solução mágica para isso. Cada aplicação tem um contextoção mágica para isso. Cada aplicação tem um contexto e precisa ser analisado. Por isso que nós devemos entender que não há nada de errado também em usar monolitos. Isso volta lá à primeira cilada de falar de microserviços. Isso volta lá a primeira cilada de falar de microserviços. Eu acho que em 2025 nós não estamos mais com aquele mito que microserviços é a arquitetura bala de prata que resolve tudo. Mas ali, mais ou menos em 2019, 2020, 2021, figurou muito essa questão que a arquitetura monolítica é errado. É algo que, se você está fazendo, você não é bom tecnicamente ou a sua empresa é menor que outra. Não, a arquitetura monolítica é uma decisão de arquitetura, como também a arquitetura de microserviços. Se a sua empresa não está usando a arquitetura de microserviços, não tem problema nenhum. Não há nenhum demérito nisso. Às vezes a gente quer buscar exemplos de, ah, tem aplicações de empresas grandes que são monolíticas? Tem, uma aplicação que todos vocês usam todos os dias, o próprio GitHub que é construído em Ruby. Imagina hoje, ainda mais, quantas coisas que o GitHub não faz, porque o GitHub acaba sendo uma rede social, é um portal de código fonte você consegue fazer a edição de código por requests GitHub Actions e mais um monte de outras coisas tudo isso está dentro de uma mesma aplicação, então não há nenhum demérito nisso nós conseguimos recuperar Oi é sobre sobre essa questão né microserviços não ser bala de prata também é e um sistema monolítico é se torna mais barato um sistema monolítico do que de micros serviço ou isso indifere porque por exemplo se eu começar um sistema hoje é o bicho eu não tenho dinheiro para manter várias instâncias que é o micro serviço tem um micro serviço de pagamento micro serviço não sei o que eu vou ter que subir várias máquinas um sistema um leite se torna mais barato em questão disso, ou dá para estruturar mesmo o preço aí, não vai importar a arquitetura que você decidir? Foi boa a sua pergunta, inclusive, eu até estou falando aqui de sistemas monolíticos sem considerar, imaginando que vocês saibam, tem alguém aqui no nosso grupo, não tem problema nenhum, tá? Você não sabe o que é um sistema monolítico ou está meio em dúvida do que seja pode colocar aí no chat se tiver alguém, não tenha vergonha a gente está aqui para aprender deixa eu beber um pouco de água eu já explico isso e explico também a dúvida do Demonte Ferreira Oi Pedro posso só me chamar do Demonte e dar uma opinião claro questão de arquitetura além do Demonte dar uma opinião. Claro. A questão da arquitetura, eu acredito, vendo o Full Cycle 3 e lendo alguns livros em torno desse assunto, que a arquitetura não é simplesmente escolhida por bel prazer do arquiteto. É muito mais derivado do contexto que a empresa se encontra do que eu quero ir lá e fazer um monolito para economizar. Porque, assim, o negócio como um todo, a empresa como um todo, é algo evolutivo. A empresa não fica estagnada sempre fazendo a mesma coisa para o resto da existência dela, ela vai evoluir conforme o mercado evolui da mesma forma o ecossistema de desenvolvimento de software vai evoluir conforme o mercado evolui, ele não para o papel do arquiteto nesse meio todo é justamente entender o ponto do mercado e entender o negócio, o momento que o negócio está para poder definir a melhor arquitetura e a partir disso obter algumas métricas. Nessas métricas ele vai avaliar se uma arquitetura que foi definida sei lá, em 2020 ainda é viável em 2025 considerando todas as alterações que houve em torno do negócio e do definida, sei lá, 2020 ainda é viável em 2025, considerando todas as alterações que houve em torno do negócio e do objetivo e restrição do negócio. Acho que é mais esse pensamento que eu construí nos livros do Neil Ford, livros do Groesman, algumas coisas assim. Ninguém falou aqui que desconhece o termo de arquitetura monolítica, só para ponderar, vou explicar de uma forma bem simples. Imagine que você tem uma empresa com e-commerce que tem vários setores, tem o setor de vendas, tem o próprio RH da empresa, setor de expedição, então no arquitetura monolítica tudo isso está concentrado ali no mesmo projeto quando você sobe, você faz o deploy de todas essas funcionalidades ao mesmo tempo, não tem uma independência entre elas então isso é uma arquitetura monolítica microserviços é justamente quando eu começo a quebrar esses contextos, gerando aplicações menores que vão acabar se comunicando ou de forma assíncrona ou de forma assíncrona, e não importa, mas aí eu consigo ter uma interdependência maior dessas aplicações, uma interdependência maior dessas aplicações, porque no momento que eu fizer, isso depende de como está organizado também, você pode ter uma arquitetura de microserviços em que os serviços são dependentes, mas a ideia é que você suba, por exemplo, o serviço de nota fiscal eletrônico ao acontecer algum problema, os outros serviços, em tese, não seriam afetados ou grandemente afetados. Obviamente, uma arquitetura de microserviços, ela tende, tá? Observe o que eu estou falando, ela tende, não existe uma verdade. Ela tende a ser mais cara para poder manter do que um monolito. Porque, como você tem apenas uma aplicação só, então se torna mais fácil em todos os sentidos, desde desenvolver, fazer debug, fazer deploy dessa aplicação. É apenas uma aplicação. Quando você tem microserviços, aí você vai ter um banco de dados para essa aplicação, uma esteira de CI, normalmente mais desenvolvedores alocados. Se tem empresas que você tem uma faixa muito pequena de desenvolvedores, você tem muitas aplicações, a arquitetura de microserviços está sendo implementada de forma errada. Então, quando a gente fala para o custo, não é só o custo ali do deploy, você tem o custo todo da empresa, porque você acaba gerando novas equipes que vão gerir aquilo ali então, a princípio sim você tem um custo maior porque você vai ter mais ferramentas são mais aplicações, são mais problemas acontecendo, se essas aplicações se comunicam de forma assíncrona, vão ter brokers ali no meio você vai ter que entender essa comunicação que está acontecendo, as mensagens que estão falhando, vai ter que reprocessar vai ter que fazer a princípio uma migração desses dados é muito mais complicado por isso que quando você toma uma decisão de ir para microserviços é uma decisão que tem que ser muito pensada, que é igual quando você quebra um ovo. Tem como você, você pode até, sei lá, pegar um super bonder, ou pegar uma fita adesiva e tentar colocar a casca no lugar. Mas não é a mesma coisa mais. Então, você dificilmente consegue fazer a reversão. Então, as empresas, elas tomam essa decisão justamente quando elas querem crescer em todos os sentidos, não é somente no técnico. Pegando um caso, não sei se alguém que trabalha no mercado livre, há 15 anos atrás, o mercado livre tinha apenas um monolito, basicamente, que era o deploy com o ponto or. O deploy tinha que ser feito às 3 horas da manhã. Hoje o Mercado Livre tem milhares de aplicações com esses microserviços. Então, olha a quebra. Mas para o Mercado Livre chegar ao ponto de fazer essa mudança, não foi porque, não, vamos fazer aqui a mudança porque agora a gente vai começar a usar essa linguagem aqui, e etc. Não, era uma decisão de negócio justamente porque a empresa estava crescendo, expandindo para a América Latina inteira, e você tinha que separar esses contextos para permitir um caminho mais independente para essas aplicações, alocação de squads, enfim. Primeiro, é uma decisão política. Pode ser que às vezes na sua empresa você quebra um serviço em outros menores para poder resolver alguma questão, mas normalmente isso é mais raro. Quando se toma essa decisão, normalmente você não está ou sabendo o que você está fazendo ou você está tomando uma decisão errada se você não tem um grupo quando a gente está falando de micro serviços se a gente tem um grupo assim de 30, 50, 100, 200 desenvolvedores a gente está falando de uma empresa que tem 5 10, 20 desenvolvedores você tem que ter muitas pessoas para poder trabalhar com microserviços. Estona muito mais caro. Você multiplica os problemas em cada aplicação. Então, que fique claro, essa questão não existe nenhum demérito. Isso é apenas uma escolha de arquitetura. A questão do monolito eu já expliquei o que é, então eu vou passar eu criei aqui o guia pra poder salvar o seu monolito e a gente vai falar aqui o caso da própria Fulsight com que nós temos o nosso monolito então temos aqui oi boa noite interrompendo um pouco antes de você passar para o próximo tópico. No caso, se eu tiver um monolito e de repente vem uma funcionalidade que não tem nada a ver com o que eu tenho dentro do meu monolito, ela é meio que completamente independente. Faz sentido eu ainda integrar nesse monolito? Sim, é uma boa pergunta. Já adiantando aqui um pouco do que a gente faz para a nossa aplicação, vamos conhecer aqui o case monolítico que eu vou falar dessa pergunta. Quem que é? O Maxwell, né? Que fez a pergunta. Max, pode chamar o Max. O Max. É, porque tem o Maxwell que acabou mandando mensagem ali, achei que era a mesma pessoa. Para vocês poderem conhecer como que é a arquitetura hoje aqui desse nosso monolito, nós temos mais aplicações, não é somente essa aqui. Esse que está aqui em azul é o que a gente chama de Code Platform, que é a aplicação Backend, uma API REST, que também tem a parte administrativa que vocês não têm acesso. É uma aplicação com um Symfony 2.8, que é lá de 2013, 2014. Na verdade, ela começou com o Symfony 2.6, depois a gente conseguiu avançar até onde foi. 7.1. É. Com o PHP, que foi avançando até o 7.1, mas começou com o PHP 5.5 e rodou muito tempo com o PHP 5.5, depois foi pro 5.6 e aí nós fizemos algumas coisas pra poder migrar aí pro 7.1, então essa aqui é a arquitetura, é uma aplicação muito legada porque PHP 7.1 sei lá, desde quanto tempo, não sei, que ele foi lançado, mas o Symfony foi lançado desde quando, essa versão foi lançada desde quando a aplicação foi construída. Ela tem comunicação com plataformas de terceiros, a gente comunica com Salesforce, comunica com gate de pagamento, com algumas outras questões educacionais, tudo que vocês vão fazendo ali é analisado, nós temos dashboards dos cursos e tudo mais, para que a gente saiba o que vocês estão estudando, colhe o feedback de vocês e continue gerando os treinamentos com qualidade como a gente gera. Quando é necessário trabalhar com cache, é o famigerado red stack também, mas a gente vai falar disso um pouquinho mais para Quando é necessário trabalhar com cache É o famigerado RedStack também Mas a gente vai falar disso um pouquinho mais pra frente Banco de dados é só uma SQL 8 Que na verdade é até uma instância pequena que a gente usa de cabeça Agora eu não lembro as configurações Mas começou com um MySQL 5.3, eu acho Depois a gente conseguiu fazer a migração facilmente. E tem o front-end. Então, aquela aplicação que vocês acessam lá, toda bonitinha e tal, os módulos com as aulas, não é esse Code Platform. Ela está apenas pegando os dados dela. Então, tem a aplicação React.js 16 com o Vit.js. A gente, na verdade, iniciou com o Create React App, que nem é recomendado mais. Depois nós fizemos essa migração. Quando é necessário fazer uma comunicação com outras aplicações de forma assíncrona, é usado o ReptMQ. Quando vocês vêm aulas, faz requisição de certificado e tudo mais, isso acaba gerando eventos que vão para outras aplicações que acabam pegando esses eventos e fazendo outras coisas, nota fiscal e etc. E aí vem a pergunta do Max. Se surgiu uma nova funcionalidade, o que eu vou fazer? Eu vou colocar dentro desse monolito aqui azul ou posso criar uma nova aplicação? É uma excelente pergunta. Para o nosso caso, algumas aplicações que já estavam aqui dentro, nós decidimos deixar morta. Exatamente por quê? Porque estava inviabilizando não só a questão técnica, mas a evolução da experiência de vocês na questão de estudo eu vou dar o exemplo de um fórum logo no começo dessa plataforma lá atrás tinha o fórum dentro da própria plataforma e a coisa era feita com AngularJS depois eu vou falar como que ela era mas assim, ela é muito lenta, consumia muita memória no browser, e se a gente continuasse a evoluir, principalmente a questão ali do front-end, não ia ser legal. E como nós já tínhamos um outro segmento, eu não sei quem aí já foi aluno da School of Net, a School of Net é uma outra escola do nosso grupo, nós já tínhamos criado uma aplicação de fórum usando Django, que ficou bem bacana. Então, nós decidimos depreciar esse fórum dentro da plataforma e estripamos esse fórum dessa aplicação, criando o fórum dessa plataforma aqui. Então, essa decisão é legal quando você vê que não há muito futuro para essa nova funcionalidade. Então, você, às vezes, tira essa funcionalidade da sua aplicação ou somente cria uma aplicação nova. Isso não significa que você está fazendo microserviços, tá? Mas é apenas uma decisão também de separação. Quando a gente estrangula, vai estrangulando para tirar algumas funcionalidades novas, isso é um padrão também chamado de Strangler. A gente está estrangulando a aplicação para poder tirar pormenores ou contextos que não fazem sentido mais. Aí a questão da sua resposta é depende, tem que ser analisado. Se você vê que essa nova funcionalidade não vai ter muito futuro, ela vai emperrar na questão técnica, você vai analisando vários sentidos. Se não for viável, crie uma nova aplicação, se não, adicione. Muitas coisas novas vêm sendo adicionadas nessa aplicação aqui, mas essa questão do fórum do aluno, estatísticas do que vocês vão fazendo, deixa eu ver o que mais que a gente tem. Parte de marketing, que antes essa aplicação fazia também, nós criamos uma outra aplicação e depois até terceirizamos também. Porque a gente tem a nossa parte de desenvolvimento aqui, mas a gente não almoçou de fair house também. Então, muitas soluções que nós usamos São soluções já prontas Beleza? O Guilherme colocou ali o Strangler Tem o site do Martin Fall E também tem outro site bem bacana Focado em microservices Então no caso, só para tirar uma dúvida Mais outra Então mesmo que essa Funcionalidade não seja completamente independente, eu vi a resposta do outro colega lá. Então, se eu colocar isso em outra aplicação, ela não seria um microserviço, seria realmente uma outra aplicação, não é isso? Sim, você pode ter vários monolitos dentro da sua organização. No nosso caso aqui, essas aplicações, elas estão mais para uma arquitetura monolítica do que para uma arquitetura de microserviços hoje. A gente tem essa separação das estatísticas e do fórum, mas nós temos hoje muita pouca comunicação assíncrona. Ela não tem aquela organização que você tem as aplicações se encadeando para poder efetuar um processamento de um negócio. As comunicações que nós temos, você acabou de ver aqui uma aula requisitar um certificado, aí cai para uma outra aplicação que ela pode estar consumindo de forma assíncrona, não significa que você tenha uma comunicação assíncrona, que é de microserviços. Mas a gente apenas tem uma outra aplicação monolítica que está fazendo esse processamento de negócio. Beleza? Beleza. Desculpa, Luiz, qual que é o tamanho da equipe dos senhores? Hoje nós temos, deixa eu até contar aqui, que nós temos hoje apenas seis desenvolvedores. E, obviamente, não daria para poder trabalhar com microserviços com uma equipe desse tamanho. Então, é uma equipe muito pequena que a gente tem. A gente tem desses seis desenvolvedores, dois são mais especializados em front-end e o restante dos desenvolvedores são focados mais em back, que é a nossa principal necessidade hoje. Porque basicamente, de front tem a aplicação do fórum que vocês utilizam, a aplicação principal dos estudos e as nossas landing pages dos lançamentos que nós fazemos. Então, ainda mais agora com o IA, a nossa produtividade aumentou ainda mais, a gente nem vê necessidade de contratação no momento beleza deixa eu fazer uma pergunta aqui rapidinho acho que o som de vento deve ter parado aí ano passado, não vou lembrar quando a Fullcycle fez uma live com um arquiteto de software especializado em sistemas de alta criticidade. A minha dúvida é, por exemplo, em um sistema enterprise, como a gente está vendo nas aulas do primeiro módulo, de gestão de arquitetura. Até que ponto utilizar os conceitos de sistema de alta criticidade no sentido de ser um sistema de garantir a resiliência e tolerância a falhas Utilizar os conceitos de sistema de alta criticidade no sentido de ser um sistema de garantir a resiliência e tolerância a falhas é benéfico para uma empresa do que não usar isso. Porque assim, digamos que, por exemplo, um monolito tem algumas táticas de tolerância a falhas ali, mas até que ponto isso vai ser benéfico para a empresa no sentido de custos e eficiência das operações do sistema no geral? Essa questão da arquitetura monolítica sobre resiliência a falhas, muitas vezes a gente pode dar a entender que uma arquitetura monolítica não é resiliente a falhas. Eu vou dar um exemplo de onde que a arquitetura de microserviços pode quebrar. Você pode muitas vezes ter uma comunicação síncrona entre os seus serviços, então se um serviço lá na ponta cai, uma malha de outros podem não funcionar. Aí a arquitetura de microserviços faz com que seja pior ainda, porque às vezes você vai demorar a identificar onde está o problema. Então, não necessariamente uma arquitetura de microserviços, ela traz essa resiliência. Ela começa a trazer quando você vai para uma comunicação assíncrona e começa a trabalhar com Event Driven Architecture, que são assuntos que estão aí no próprio MBA. Então, é necessário analisar primeiro a decisão de negócio. Eu vou dar um exemplo aonde que a gente não teria uma grande disponibilidade pensando em questão de negócio. Não sei se alguém aí já comprou ingresso do MBA. Alguém aí já acessou a plataforma para poder comprar lá? Assistiu? Faz muito tempo que eu não curto basquete mais. Acho que eu curtia mais quando era criança. A regra de negócio por trás, o Luciano ali sim. Quando eu vou comprar um ingresso, eu posso ter outras pessoas reservando aquele lugar. O primeiro que compra é o primeiro que fica com aquele lugar. As outras pessoas vão oferecer descontos e tal, você vai ter uma mensagem que aquele lugar não está reservado. Então, nós estamos priorizando consistência e não disponibilidade. Se falhar, paciência. É uma decisão de negócio. Se eu mudasse a decisão de negócio para que, ah, não, eu fiz aqui a reserva, mas eu só vou contabilizar depois, isso mudaria totalmente a dinâmica da compra desses ingressos. Imagina, todo mundo reservou o lugar a 10. Da compra desses ingressos, né? Imagina, todo mundo reservou o lugar a 10. Só daí 5 minutos que essas pessoas vão saber se esse ingresso está reservado ou não. Faz sentido? Quando eu tenho algo assim, eu consigo estar mais disponível. Estar mais disponível. Estar mais disponível. Estar mais disponível. É porque quando eu quero estar mais disponível, eu posso me afastar um pouco da consistência e depois a gente vai lidar com ela lá na frente. Consigo até ser mais resiliente ali no momento, né? Porque se eu devolvo a resposta para esses consumidores na hora, não tem que fazer o processamento depois? Como que vai ser esses custos? Pois, uma dúvida rápida. A quantidade de requisições síncronas e assíncronas vai ser um parâmetro para caminhar pelo monolito ou pelos microserviços. Por exemplo, se tiver uma quantidade gigante de requisições que precisem ser respondidas de forma síncrona, talvez um monolito seja uma melhor opção em contrapartida ao microserviço. Deixa eu só terminar a questão do Pedro Sandrin, então eu tenho que analisar primeiro o que faz sentido pro negócio, se eu quero ser mais disponível ou se eu quero ser consistente normalmente é difícil você conciliar essas duas coisas ou você preza mais pela consistência, ou se você está afastando dela, você vai ter a consistência eventual, que você vai ter um dado não atualizado durante algum tempo, e aí ele vai demorar alguns segundos ou minutos para que a gente veja de fato qual é o lugar reservado. Pro MBA tem que ser reservado exatamente agora. Então, isso aí simplifica muito mais em questão técnica. Isso aí simplifica em questão técnica. Não somos muito resilientes nesse caso, porque vai acontecer falhas, você vai devolver mensagens para o usuário que ele não conseguiu reservar o ingresso. Então isso depende muito. Pensa, a gente está falando do NBA, o maior basquete do mundo. Então isso depende muito. Isso depende muito. Pega o próprio Stack Overflow. O Stack Overflow é uma aplicação monolítica também. Na verdade, eles têm um servidor, é Barry Metal, não é cloud, eles não usam nada em cloud, com dois servers de Redis. Eles não têm processamento, não é da pegada deles fazer a divisão ali para outras aplicações. Então, em questões de custos, volta aquilo que eu estava falando lá atrás. Tente-se a ser maior, mas a questão é a gente ter que olhar para o negócio. Você pode ter um custo maior, mas ele te rende 10 vezes mais retorno. O custo, por si só, ele não é necessariamente um problema. Ele é um doce, que você tem que analisar. Se você gastar 100 mil reais por mês de infraestrutura, mas você tiver o retorno de 10 milhões, poderia falar que a infraestrutura com 100 mil por mês é caro, né? Mas me retorna 10 milhões. Poderia falar que a infraestrutura com 100 mil por mês é caro, né? Mas me retorna 10 milhões. Se eu tivesse, às vezes, com uma arquitetura monolítica, eu poderia estar gastando metade, mas poderia reduzir o meu ganho também pela metade. E aí, qual decisão você tomaria? É, no caso aí, por exemplo, eu não tomaria decisão, né, porque eu tô aprendendo, né, mas acho que, assim, eu entendi o que você quis dizer, vai muito mais do objetivo e contexto do negócio do que ele tem em mãos, né, porque tipo, entra o que o amigo aqui disse no chat, teorema CAP, né? Então você vai ter vários de trade-offs. Você vai ter os trade-offs pra atender os objetivos do negócio. Então, por mais que resiliência seja algo importante, disponibilidade pode ser mais importante pro negócio do que resiliência. Então aí já muda o contexto da situação, né? Pegando como exemplo a gente, nós temos uma equipe de seis desenvolvedores. Já entrou-se em discussão essa questão de divisão de microserviços, mas ela já foi descartada. Por quê? Com uma equipe desse tamanho, se a gente fizesse algumas quebras, aí seria mais um deploy para se preocupar, mais uma escala, mais um monitoramento, mais problemas na hora que você vai analisar quando acontece um erro. Muito mais, você escala o número de preocupações. É por isso que você tem que ter uma equipe alocada para isso. É uma decisão, primeiro, de negócio. Você vai ter ali as squads que vão ser donas daquela aplicação, e aí você tem a independência. Essa squad aqui, eu tô dando um exemplo de um e-commerce, de novo. O que é mais importante pra um e-commerce? Vender. Então, nesse microserviço aqui de vendas, nós vamos colocar a equipe mais talentosa nossa, porque essa aplicação aqui é o core, ela tem que funcionar bem, tem que vender bem. Agora, num microserviço lá que vai fazer alguma coisa de logística, eu posso colocar, não é nenhum depreciamento, mas desenvolvedores que estão chegando na empresa, a gente pode alocar ali naquela squad, porque eles vão pegar experiência, se acontecer falhas, não vai custar tão caro, a gente não vai perder dinheiro, e esses desenvolvedores depois, quando eles evoluíssem, eles poderiam ir lá para o time de vendas. Então, essa alocação, essa diferença não só técnica, mas cognitiva também é importante. Você tem caminhos, apesar de eles estarem relacionados, que as aplicações vão se comunicar de alguma forma, mas eles têm um caminho distinto. Enquanto essa aplicação aqui, a gente vai colocar muita tecnologia e tudo mais, essa de logística, ela pode usar alguma tecnologia mais legada, ela vai por algum caminho que não precisa de mudanças tão drásticas, enfim. A gente pode tomar essas... Isso são decisões de negócio, entendeu? Agora, sobre a dúvida do Davidson, que eu esqueci, pergunta de novo, Davidson, a cabeça não está funcionando, manda aí de novo que eu falo sobre. Desculpa até ter interrompido, porque eu imaginei que estivesse concluído, mas o que eu tinha perguntado foi com relação ao seguinte, a quantidade de requisições síncronas ou assíncronas seria parâmetro pra gente definir se a estratégia melhor seria fazer uso do monolito ou do microserviço pra evitar, por exemplo, latência dupla, essas coisas assim. Sim, sim, beleza. Vamos pegar aqui um musical pra deixar isso aqui mais claro. Essa questão do número de requisições, ela pode sim ser um parâmetro, mas não somente ele. Vamos imaginar que a gente tem aqui uma aplicação e aí vai chegando aqui milhares de requisições. Vamos supor que seja 100 mil, um bom número, um milhão. Se essa aplicação demora apenas 4 milissegundos para poder atender essas solicitações, e essa aqui é uma aplicação monolítica, eu não teria grandes problemas, porque a grande questão da comunicação síncrona é que você precisa fazer a chamada, esperar o processamento acontecer e devolver a resposta só depois disso. E você fica com aquela conexão bloqueada ali. Você tem aquele recurso de rede alocado. Então, você vai alocar também CPU e memória. Se você tem um processamento de 4 milissegundos, mesmo que seja uma aplicação monolítica, dificilmente a gente vai ter problemas, porque a alocação de recursos é devolvida rapidamente. Então, o número de requisições somente não é parâmetro, porque eu tenho que analisar o contexto da aplicação. Agora, se dado o número de requisições, eu atendo em 4 milissegundos a resposta, vai se crescendo, aí só que começa a demorar um minuto, aí sim eu começo a ter um problema que durante um minuto eu estou sequestrando ali uma thread memória disco e mais um monte de outras coisas então o que está acontecendo aqui é muito I.O é banco de dados é banco de dados e I.O é um dos principais motivos de lentidão de aplicação então eu tenho que analisar isso em conjunto com outras variáveis. Entendeu? Se eu tiver muitas chamadas, mas devolver a resposta... Seria mais lento se fosse microserviço? Sim, no monolito está custando um minuto e microserviço, em teoria, custaria mais, né? Teria a comunicação entre eles, ou não? Não, aqui no mais, né? Teria a comunicação entre eles, ou não? Aqui no... Aí vamos pegar o caso de uma aplicação de vendas, que eu acho que é um exemplo bem categórico, né? Eu tenho aqui vendas... Luiz, eu posso responder essa pergunta dele? Eu tenho uma situação real dentro aqui da empresa. Posso explicar? Pode, manda ver. Pronto. Eu trabalho para a Riachuelo. A Riachuelo, ela tem só de TI, ela tem umas 600 pessoas. Eu não sei exatamente quantos desenvolvedores. Então, toda parte de infraestrutura, desde o desenvolvimento até a infraestrutura, é tudo dela. Eu trabalho especificamente na parte de mensageria, entrega de e-mail, WhatsApp, SMS, esses três serviços. Simplesmente, a gente trabalha com a SendGrid para entregar, no caso, de e-mail. Já para caso de no caso de e-mail. Já para caso de decisão de negócio, para uma empresa desse porte, tudo é microserviço lá. Cada squad trabalha com seus microserviços totalmente separados, já porque não tinha como ser monolito. Você já entra trabalhando com microserviços, porque é muito squad, é muito serviço lá, são inúmeros serviços que eu nem conheço todos ainda. Aí, o que aconteceu? A gente pegou, teve que desenvolver o sistema de mensageria para entrega de e-mails. Eu sou responsável por todas as escolas que precisam enviar e-mail, passa pelo meu escudo onde eu trabalho. Esse serviço de e-mail, ele chega a dar 600 mil e-mails por dia. 600 mil parece pouco, mas o problema é que 600 mil e-mails por dia. Aí, 600 mil parece pouco, mas o problema é que 600 mil, na maioria das vezes, acontecem entre 8 da manhã até 10 horas. Então, pico de mensagem. Se a gente colocasse isso para uma máquina só receber essas requisições e entregar, a latência ia crescer demais. O próprio serviço da da da Sandy grid a latência dele é grande tem hora que chegar a dar 200 milissegundos que a gente fez pegou um micro serviço que só para o Kafka, o outro pod, que é outro microserviço, recebe, lê esses dados e manda para a SendGrid. Então, hoje a gente não tem uma latência, uma latência muito pouca, porque a gente concentrou tudo num microserviço que tem vários pods, só para receber as requisições, e outro microserviço que tem vários pods só para receber as requisições e outro microserviço que lê do Kafka só para enviar as requisições. Posso só comentar? Sim. Pode comentar. Tudo bem. O meu ponto foi só com relação ao seguinte. Esse cenário que o Paulo falou é um cenário onde é permitido requisições assíncronas. Mas eu estou falando em cenários onde tem a necessidade de requisições assíncronas. Nesse caso, onde tem a necessidade de requisições assíncronas. Se o monoreto não seria uma opção melhor pelo fato de economizar essa questão da latência, uma vez que eu estou com a minha requisição lá segurando para dar resposta para o meu cliente e eu preciso dar uma resposta, se eu estiver no cenário de micro serviços eu vou passar por N pontos até eu gerar essa resposta então no monolito talvez não, mesmo que não seja tão performático em teoria quanto em distribuir os processos. Minha dúvida seria se, por exemplo, em cenários símpronos, talvez o monolito tivesse melhor performance. Sim, por isso. O microserviço não está proibido de ter a chamada símprono. É permitido. Faz parte do microserviço não está proibido de ter a chamada síncrona é permitido faz parte do microserviço também ter uma chamada síncrona deveria ser a exceção, mas é permitido o que cabe nesse exemplo que o Luiz está colocando aqui é um circuit breaker que nem ele comentou ali a chamada prendeu e atravessou tem que ter um circuit breaker para poder validar se aquela chamada está derrubando alguém, desliga a chave, para as próximas nem chegarem até aqui. Logo essa situação, e aí na retentativa possível, ativa de novo a chave do Circuit Breaker e volta a utilizar. Eu vejo assim, pelo menos, não vejo uma arquitetura de microserviços onde tu vai ter só comunicação assíncrona. Eu acho que vai ser uma mescla entre assíncrono e síncrono, um pouco de cada. Mas quando utilizar o síncrono, tem que ser bem utilizado com as ferramentas necessárias. É a minha visão. Vamos pegar aqui o caso para poder justamente o que o Paulo e o Roberto estão falando, pegar o caso de vendas. O que você acha, Davidson? A gente está recebendo aqui um milhão de chamadas e aqui no momento eu tenho o meu banco de dados que armazena aqui o pedido e depois eu tenho que fazer o envio de e-mail com a confirmação para o cliente e tudo mais e tenho que fazer uma comunicação aqui com uma outra aplicação de NFE. Se chegar ao ponto dessa aplicação de vendas começar a gargalar, o que eu tenho que fazer? O que você vê que eu teria que fazer aqui? Então, por exemplo, esse caso, na minha opinião, em nenhum momento precisa ter uma resposta síncrona. Basicamente, você vai distribuir nas filas e aí no seu broker, e aí vai ser consumido de acordo com a sua arquitetura. Meu único ponto de dúvida é se eu preciso dar alguma resposta. Por exemplo, a gente estava desenvolvendo um projeto onde a gente precisava que um profissional enviasse uma foto para o nosso sistema e ele só pudesse continuar com o trabalho dele, tendo o retorno que essa foto foi registrada e é válida. E aí, nesse cenário, a gente estava discutindo se seria melhor a gente, através do, talvez, do device do cliente, criar alguma estrutura de comunicação assíncrona, ou se a gente faria, seguraria a resposta do cara, a requisição do cara e enviaria. E aí, nisso, cara, a requisição do cara e enviaria. E é isso. Assim, a dúvida é se a gente vai trabalhar com síncrono, talvez fosse mais conveniente. É sério que o microserviço pode responder síncrono, mas talvez fosse mais conveniente ele estar todo o processamento em um local só para poder gerar a resposta para o cliente, mesmo que seja um pedaço da aplicação. Já no caso de alguns contextos a mais, algumas unidades de negócio a mais, não teria o que fazer, teria que ser em outro serviço, mas aí deixaria de ser síncrono. Mas o ponto era que a gente estava analisando se seria viável a gente trabalhar nesse cenário síncrono Simples e unicamente o cliente Mandou a requisição pra gente, a gente conseguiu processar E já retornar pra ele, imagino que teria que ser No monolito, ou se a gente Poderia pegar isso E distribuir, e em algum momento O cliente receber a mensagem falando que Pode continuar, basicamente Foi esse o porquê da minha dúvida Vamos pensar esse cenário aqui. Se eu trabalho totalmente síncrono, e aqui eu poderia ter dois microserviços. Eu tenho esse aqui de NFE e o de vendas. Então, quando chegou a venda, eu vou fazer tudo síncrono. Eu vou acessar o banco de dados, aqui eu vou acessar a coisa externa, e vou fazer a chamada aqui para poder fazer todo o processo. Se eu recebo muitas chamadas, vai chegar um ponto em que eu posso pensar assim, ah, vou escalar isso aqui de duas formas. Eu vou tanto aumentar os recursos de CPU e memória e vou criar réplicas, beleza? Então, a gente vai aumentando tudo. Se eu aumentar aqui, eu vou ter que aumentar o de NFE também, senão ele não vai suportar, né? Porque eu tenho uma chamada síncrona acontecendo aqui. Agora, e o serviço de terceiro? Às vezes o serviço de terceiro, às vezes não, ele está numa outra rede, vai ter a latência e com certeza ele não vai suportar esse volume alto de chamadas que eu tenho. Ou isso aqui vai custar muito caro. Mas também, mesmo que eu escale isso aqui absurdamente, o meu banco também não vai suportar. Eu vou ter que escalar ele para cima também, se eu estiver utilizando o banco tradicional. Nem escala horizontal, eu tenho só vertical mesmo, CPU e memória. Então, isso aqui vai se tornando inviável, porque a solução acaba sendo escalar recursos ou criar réplicas. Então, isso aqui vai custar muito caro em relação ao que a empresa vai faturar. Por isso, penso assim, a venda precisa acontecer devidamente agora? Não, eu preciso registrar o meu pedido, mas se eu demorar alguns segundos ou alguns minutos para poder fazer o processamento do cartão, enviar o e-mail para o cliente, logo, não tem problema. Porque aí, nesse caso, então, eu só teria aqui o banco de dados para poder registrar esse pedido, e mesmo assim, isso aqui não seria muito grande para poder fazer todo o arco da minha transação, então eu elimino toda essa parte aqui, posso eliminar toda essa parte fazendo que esse processamento seja assíncrono. Então pensando assim, poxa, se eu demorar uma hora para poder gerar a nota fiscal do cliente, tem problema? Não. Então quando o pedido cai de forma assíncrona para a NFE, se eu tiver um serviço mais modesto, que demora mais para executar, nós vamos acabar tendo mais economia. Então, muitas vezes você pensa assim, preciso fazer o pedido agora. Será realmente que você precisa fazer esse pedido agora? Muitas vezes a gente de tecnologia entende que tudo tem que acontecer de forma síncrona. Porque a programação meio que ensina tudo isso, né? Você não vê um processo demorando um tempo pra poder acontecer. Você quer fazer tudo, banco de dados, HTTP e tudo mais. E tá aí o grande problema. Guarde essa frase. O nosso projeto ou aplicação sempre se pauta pelo elo mais fraco. Sabe onde tá o elo mais fraco? Banco de dados, aplicação externa, ou aquele projeto ali que não tá na frente, tá acessível. Eu posso ter essa aplicação de vendas feita em Rust. Poxa, a aplicação totalmente performática, mas o meu banco de dados agarra ela, não adianta. E dá uma parada que dá para fazer também, pensando nesse contexto específico que você explicou de vendas. Por exemplo, o sistema de NFE não precisa necessariamente estar online, você pode estar cá para um sistema de mensageria e consumir depois. Porque como é uma nota que o cliente está pouco preocupado com a nota imediata ali, pode chegar depois, não é um serviço essencial crítico, é um serviço essencial. Mas ele deixa de ser crítico, né? Sim. E aí, entra ali o Franklin, tá falando, depende da empresa se é um delivery precisa na hora, mas outros pode demorar mais tempo sem perder milhares de vendas. O ponto é que eu não posso perder venda. E aí eu posso pensar aqui numa outra coisa. Vamos pagar tudo isso aqui. Ah, mas então eu poderia não ter microserviço e esse NFE fazer parte aqui de vendas? Boa dúvida, será que eu precisaria de fato ter um microserviço ou eu poderia ter uma outra perspectiva da minha aplicação com um processo em background ali que consumiria de uma fila assim ó, exatamente dessa forma eu poderia ter uma outra perspectiva da minha aplicação com um processo em background ali, que consumiria de uma fila, assim, exatamente dessa forma. Eu teria aqui um broker da vida, que eu mando a mensagem para cá, e aí... Oi? Quem está falando? É o Henrique? Não sei se alguém falou alguma coisa. Então, aqui, o NFE vai ficar aqui juntinho, certo? Eu posso ter o NFE que faz parte da mesma aplicação monolítica, nesse caso, consumindo aqui do meu broker depois, tendo a comunicação assíncrona, sim. Comunicação assíncrona não é algo que está grudado igual carrapato em microserviços. Não tem uma relação. É porque tente-se a recomendar que se você puder, quando você trabalha com microserviços, se você puder ter uma comunicação assíncrona, você tem o quê? Uma interdependência entre eles. Justamente porque quem está consumindo pode consumir no momento mais oportuno, pode falhar e voltar a consumir depois. E também você acaba tendo outros benefícios, como interdependência tecnológica, eu posso criar lá outra aplicação com uma outra linguagem, num outro contexto mais adequado. Mas eu poderia fazer isso aqui? Sim. Mas qual que é a questão? O problema é que quando eu estou no monolito, tudo acaba sendo um só, mesmo que você esteja no mesmo projeto. O código de vendas está no mesmo lugar de NFE. Então, só isso aqui já aumenta os riscos de problemas. Quando eu faço uma mudança em NFE, eu posso quebrar vendas. Ou quando eu faço uma mudança em vendas, eu posso quebrar NFE. Mesmo que esse camaradinha aqui só roda em background lá. Eles estão compartilhando alguma coisa bibliotecas, alguma configuração, então eu tenho esse problema e também se eu tiver várias pessoas mexendo, eu não consigo ter essa independência de contexto porque todas estão ligadas da mesma aplicação, então eu não consigo fazer às vezes uma alocação eficiente pra poder fazer essas duas coisas evoluírem de forma bacana. Então, por isso que a separação, quando eu tenho várias squads, é melhor, porque eu não tenho esses conflitos de interesses dentro do mesmo projeto. É, o maior problema, assim, que eu vejo de usar monolito, isso é opinião minha, lógico, todos podem discordar, mas eu acho que um monolito gera complexidade exponencial ao longo do tempo. No sentido de qualquer mudança que você faz, é passível de quebrar o sistema inteiro. É possível, com certeza. Com certeza. Então, assim, não tem nenhum demérito de você usar um ou outro Pra deixar isso bem claro, acho que essa discussão aqui Deixa isso bem claro Então voltando pro monolitão aqui da Fullcycle Eu tenho uma dúvida ali, naquele exemplo Aquele exemplo da NFE Eu tenho duas dúvidas A primeira é Se é o monolito ali, e mesmo que a gente tenha Dois serviços no mesmo monolito, que é vendas e NFE, a gente vai ter o mesmo banco. Como que a gente escala essa parte dos dados? Porque eu tive uma experiência recente que a gente topou um Aurora Service, batemos 100% de consumo e a gente não conseguia mais escalar o banco. batemos 100% de consumo e a gente não conseguia mais escalar o banco. Então, a gente chegou no limite do que o banco podia escalar e a gente calou os recursos na frente. Como a gente trabalharia com esses dados? Sim, isso também é outro ponto. Quando você tem um monolito, você pode ter, às vezes, um contexto da sua aplicação utilizando de forma massiva o banco, enquanto outros ficam prejudicados, que eles precisam apenas utilizar ali algumas questões mais básicas a gente tem que pensar uma coisa, se banco está gargalando assim, banco é feito para poder lidar com uma alta carga de processamento se banco está gargalando é ou porque ele não está suportando o número de chamadas ou porque a sua consulta está sendo tão impactante para ele que ele está tendo que juntar tantos dados que agregado a outras consultas que vão acontecendo ele se sufoca. Então, a forma de fazer isso é justamente, em determinadas situações, trabalhar de forma desnormalizada. Essa história de normalização e desnormalização, ela surgiu lá atrás, porque lá há 50 anos e tudo mais, a gente tinha problemas de armazenamento. A gente tem problemas de armazenamento hoje? Você pode armazenar 50 gigas, 100 gigas, 1 tera, de qualquer coisa que você quiser. Armazenamento é barato. Há 50 anos atrás, não era barato. Era muito caro. Então você normalizava por isso que se criava as chaves estrangeiras. Você cria chave estrangeira na sua tabela pra você não duplicar registros. Mas a gente tem que entender que esse cenário mudou. O que é caro hoje é consulta. Você tem que ter o dado a quente, multiregião disponível em dois milissegundos. Isso é o problema. Que seja ali para... do seu API REST ou o arquivo que você quer disponibilizar para o seu usuário. O acesso ao dado em si. Então, quando você desnormaliza, você vai tender a duplicar esse dado em outras tab Então, quando você desnormaliza, você vai tender a duplicar esse dado em outras tabelas, fazendo com que essa consulta não gere essas junções, os joints, tornando mais fácil essa recuperação. Essa desnormalização pode ser aplicada em qualquer banco, desde SQL ao NoSQL, e a gente normalmente acaba fazendo tabelas flats para isso. Você cria ali uma tabela já focada, ou não precisa ser necessariamente para uma consulta, mas adequada que você vai minimizar joins ou não vai ter nenhum. Aí sim, se torna mais leve. Também você vai usar outros artifícios de banco. Cada banco tem um. Você tem as views materializadas, você pode trabalhar com cache, aí a sua aplicação pode ajudar também dela implementando cache, utilizando cache em HTTP. Então, seria para esse lado para que a gente faça essas otimizações. Beleza? Certo. E um outro ponto ali, daquele exemplo ali, é que quando tiver muitas vendas, a gente vai ter muitas NFs sendo executadas e os dois serviços juntos vão escalar. Então, tipo, um serviço chamando ele mesmo ali para fazer com que o serviço escalaria de forma desnecessária. Exatamente, porque você acaba escalando o código inteiro, né? Muitas vezes, dependendo ainda da aplicação, ela está toda amarrada. Para você poder dar uma escaladinha aqui na NFS, você acaba escalando vendas de forma desnecessária, né? Então, microserviços justamente é para poder dar essa independência entre os serviços, beleza? Beleza. Show de bola. Então, voltando pra cá. Perdão. Se você quiser responder depois, tranquilo, pra não vir com a sua apreciação, mas você puxou, eu gostaria de perguntar. Oi, Iago, eu não sei o que está acontecendo com o seu áudio, ele está um pouco abafado, mas eu não consigo entender. Está melhor? Eu não sei o que está acontecendo com o seu áudio. Ele está um pouco abafado. Está... Está melhor? Não consigo entender. Está melhor? Não, ele está abafado. Está parecendo que você está... Vi que você está perto, mas está parecendo que você está longe do microfone. Está um pouco estranho. É que está no fone. Agora tirei para o computador. Melhorou? Agora melhorou. Ah, legal. Show de bola. Voltando aqui, se você quiser responder na frente, tranquilo para não desvirtuar tanto a apresentação, mas só fazer uma pergunta, porque você puxou o assunto e eu gostaria de perguntar. Eu trabalho com microserviços faz bastante tempo, só que lendo, estudando, a gente acaba caindo, estudando bastante os pitfalls dos microserviços e alguns benefícios do monolito. Principalmente, por exemplo, estudando o CleanArc, por exemplo, ele acaba falando bastante sobre os benefícios de ter uma fronteira orina da código, né? Então, você poder chamar explicitamente os códigos de outro componente, coisa que se você tivesse múltiplo serviço, você faz, lhe chamar de HTTP. Aí, uma coisa que recorrentemente eu vejo é o quão explícito os contratos entre componentes dentro de um monolito, quão explícito eles são. Então, se você quiser fazer uma chamada para outra componente, geralmente você pode chamar a nível de código, e vai ser muito bom, porque aquilo ali está na mesma base de código, o seu linter pode pegar um problema ali dentro da água de comunicação. na base de código, o seu linter pode pegar um problema ali dentro da água de comunicação e eu ainda não cheguei a uma maneira de conseguir contornar esse pitfall do microserviço. Então, os problemas vão cascateando e você só vai descobrir uma vez que você testou todos os serviços ao mesmo tempo. Se você tem faz uma pequena modificação ali na interface pode quebrar, isso aí também pode cascatear. Então, a gente vê bastante benefício nessa parte de escalabilidade, né? Consegue escalar as partes individuais de maneira individual, horizontalmente. A gente vê o benefício organizacional de poder dividir squad e tal, mas tem esses pontos aí que eu não sei se tem mitigação. A gente vê, por exemplo, tem esses pontos aí que eu não sei se tem mitigação. A gente vê, por exemplo, GRPC, que tem, por exemplo, mitiga no sentido de você consegue definir lá os seus platobuffs, então pelo menos a chamada vai estar escrita em algum lugar, mas em vários outros sentidos isso não acontece. Eu queria saber se tem alguma maneira de conseguir alcançar isso com um microserviço. Uma vez que trocar para monolito ia ser mais complicado. Deixa eu ver se eu entendi. Você está falando sobre você testar esse cenário ali do processamento de negócio como você tem vários serviços vocês não conseguem fazer esse teste e garantir se de fato está funcionando? Seria isso? Se você tem um único serviço... É, ou se tem o end-to-end, que nem o Max colocou ali. Mas o end-to-end é extremamente mais complexo do que um teste local, né? Sim, sim. Nesse caso, para você poder fazer o contorno, eu vou colocar aqui na tela, como é que chama? Pact Foundation Test Contract. Caiu aqui no JS, mas esse repositório aqui, repositório multilinguagem, que ele foca numa plataforma de testes de contratos. Então, você vai encontrar Python, JavaScript, tem Java aqui, Ruby, PHP e tal. Então você tem aqui uma lib que vai permitir que você crie esses contratos entre os serviços, permitindo fazer esses testes. E aí você pode configurar seus testes de integração ou até testes de alto nível Com end-to-end Eu vou passar ele aqui também no chat Mas independente Por que eu não estou conseguindo passar? Aqui Estava na sala errada Independente se você vai usar isso aqui E não existe somente Expect Mas eu tenho recomendado bastante para os alunos, você tem teste de contrato, cada linguagem o framework às vezes te ajuda sobre isso. A questão é você criar esse contrato. Por quê? Às vezes você tem uma comunicação entre uma malha de serviços e não é viável você fazer um teste entre todos eles. Você não vai levantar todos esses serviços para poder executar um teste, porque isso vai ser tão caro e ineficiente também, é que você vai acabar testando alguns cenários que mesmo assim não vão te dar confiança se aquela comunicação está devidamente funcionando. Então você faz esses contratos e às vezes levanta alguns, dependendo do que for necessário, isso tem que ser avaliado para ver quais contratos devem ser feitos ou quais outras aplicações devem ser construídas. Ultimamente também, uma ferramenta que tem ajudado muito nisso é o Test Containers. nisso é o teste containers. O teste containers que foi adquirido em 2023 pela Docker, ela permite que você gerencie containers através do próprio código. Ela tem suporte para as principais linguagens de programação e a ideia é justamente ali no meio dos seus testes você pode levantar qualquer tipo de aplicação, banco de dados, qualquer coisa assim, num cenário bem leve e também eles provém aqui até uma cloud focada para que você tenha um ambiente de containers com muita performance para poder rodar esses containers. Então, isso aqui também acaba sendo interessante. Quando você, às vezes, tem um cenário que você tem que levantar várias ferramentas mesmo para valer, acaba sendo legal. Então, isso aqui também acaba sendo interessante. Quando você, às vezes, tem um cenário que você tem que levantar várias ferramentas mesmo para valer, acaba sendo legal. Então, você não tem mais que depender de Docker Composes e outras coisas. Dentro do próprio código, você pode criar todo o aparato que você precisa e, às vezes, até usar um Docker Compose puxando do próprio código. É algo também que ajuda bastante. Perfeito, Alex. Isso que eu queria saber. Beleza, vou passar aqui também o teste contêiner. Inclusive, tem material no canal que eu fiz recentemente, mostrando como você rodar múltiplas instâncias de banco, fazendo seus testes de integração, que é um pouco do que às vezes a gente precisa. Você pode levantar ali instâncias no meio do seu código e executar os seus testes. É muito bacana. Beleza? Uma perguntinha rápida para você voltar para o seu tema. Só que assim... A gente circulou aqui. Vamos lá. Só uma perguntinha. É simples. Quando você falou um negócio interessante que chamou a atenção. Falou que tinha seis devs, e a expectativa é manter com esses seis devs, porque entrou a IA e houve um aumento de performance. Só queria que tu pontuasse quanto é que tu acha que foi esse percentual de performance, só para entender mais ou menos o que a IA contribuiu em termos de performance. Tá. Em questão de mensuração, a gente teve mais 20% de performance olhando para a entrega das demandas. Porque a gente monitora tudo com gira, depois de olhar o que a gente tinha antes de usar a IA e depois de algumas semanas já utilizando, a gente conseguiu ter mais ou menos, acho que é de 20% a 25%. Não lembro exatamente o número. Boa parte do que a gente usa para IA hoje ajudou no seguinte motivo. O monolito, principalmente, ele é uma aplicação que tem muitas coisas desativadas que nós acabamos não remover, porque depois vai que a gente queira reativar por qualquer motivo então, colocar features nele, apesar que a gente usa clean architecture e várias boas práticas é complicado quanto a forma do Symfony de trabalhar então, por exemplo se eu quero colocar, estou dando o exemplo de um campo novo, eu tinha que criar uma migração aí a migração do Doctrine ela trabalha de um jeito estranho porque ela vai gerando algumas outras coisas, ali na hora que você gera um comando, identifica mudanças em entidades que não deveriam identificar, então você tem que ficar alterando algumas coisas pra poder garantir que aquela migração tá ok, aí tem o mapeamento, às vezes, do Doctrine que é antigo também, que gera alguns outros problemas, então, por exemplo, se eu quero acrescentar um campo novo, dando um contexto, ela já vai fazer todo esse processo e tira um parto de tempo que você gastaria ali, sempre às vezes algum debug alguma coisa nesse sentido e pra poder fazer a criação de testes também ah, eu acabei de criar isso aqui cria esses testes aqui, baseado nesses já existentes, a gente tem uma malha bem interessante de testes e acaba se resumindo muito, já para as landing pages que ultimamente a gente tem usado Tailwind para poder fazer muitas coisas mostrei até nessa imersão agora não sei quem está acompanhando aí, você consegue fazer a geração de telas com algumas ferramentas, a gente nem tem utilizado isso, mas em questão mesmo de HTML você não precisa mais ficar fazendo um parto pra poder ficar fazendo ajustes de design. Você tem ali já um HTML de exemplo, você já pode jogar pra ele e pedir pra ela poder fazer os ajustes conforme for necessário e você vai apenas fazendo algumas mudanças. Então, assim, muito desse processo manual, repetitivo, ele foi subtraído. E é só o começo ainda, porque os nossos devs ainda estão em treinamento, todo mundo tá, né? Em treinamento de IA. Mas, eles estão ainda estudando melhores formas de fazer aplicação disso, e só com esses 20% aí, a gente já conseguiu resolver muita, tipo assim, o nosso gira tinha muita coisa acumulada e já conseguiu desafogar muitos problemas que ficavam em meses, e agora você tem mais tempo pra poder pegar outros problemas. Qual ferramenta exatamente vocês estão usando pro Symfony? Ferramenta de desenvolvimento? É de IA no caso Qual IA você está usando? A gente está usando o Cursor Copilot O Da Anthropic O Cloud 3.4 e 3.7 Legal Só que a gente já tem Algumas configurações internas para poder acrescentar documentação, contextos. A gente já tem um amaranhado de alguns markdowns para poder fornecer contexto para ela poder trabalhar. Por exemplo, teve um dia que a gente precisou fazer uma mudança de marketing, digitou uma linha de código com uma hora, tava pronto. Basicamente, tinha que fazer alguns ajustes e tal, fez o contexto ali, o cursor, gerou tudo, executou todas as tarefas em modo agente e já tava pronto. Então, essa é a questão, né? A gente não tá falando aqui que a gente não vai contratar mais dev, tá? A gente, com certeza, vai crescer a nossa equipe, a questão no momento. Dado as prioridades que a gente tem, as demandas com os seis desenvolvedores já conseguem ser supridas. Coisa que antes com a IA, a gente estava pensando em contratar dois ou três desenvolvedores. Pensando nisso, a arquitetura vai ser modificada para atender contextos de A futuramente? A gente vai desenvolver código, por exemplo, um clean architecture ou qualquer que seja, fazendo contextos ou markdowns pra IA entender melhor o código e depois gerar automaticamente e fazer manutenção? Sim. Sim, porque hoje nesse ponto a IA é muito fraca. Se você não ensinar a ela como trabalhar com Domain Dream Design, Clean Architecture ou coisas assim, com certeza ela vai acabar tomando decisões dela e aí o ponto de você ter os fundamentos porque por exemplo, você pede pra ela criar um use case de alguma coisa, se você só pedir isso se você não falar mais algumas coisas, se você não narrar como que ela tem que fazer determinadas decisões ali, ela vai apenas criar um use case pegando uma consulta e pronto, pra ela já está de bom tamanho. Ela vai se importar com isolamento, acrescentar algum design pattern. Então, tem sim que você criar contexto para isso. Você tem que criar essas regras. Estou dando o exemplo de Domain Dream Design. Você tem regras de como trabalhar com agregados. Se você pedir para ela criar um agregado de alguma coisa sem explicar para ela o que ela não pode fazer, ela vai acabar encadeando muitas classes que ela acaba criando um repositório para poder fazer essa recuperação e às vezes você está recuperando um agregado que não faz sentido nenhum, que é pesado, e depois você só vai ver isso quando colocar a aplicação em produção esse negócio aqui está consumindo bastante recurso por quê? exatamente porque a gente não deu contexto ela vai criar uma solução da forma dela então a gente foi falando isso ultimamente a linguagem natural agora é muito importante, que é muito problema para a gente saber explicar as coisas escrito. Sabe quando você tava lá na faculdade, sei lá, no curso técnico, que te pediram pra poder fazer o algoritmo e pensar desde o começo até o fim, criar todas as etapas, que a gente acabou ficando mal acostumado, né? Por conta dos ORMs e dos frameworks. Pois é, agora a gente vai precisar pensar em cada etapa de como as coisas funcionam. A gente pode pensar, poxa, mas isso é chato de fazer. Isso pode ser chato, mas você vai gastar muito menos tempo fazendo isso do que digitando todo esse código, gerando os testes e fazendo um monte de coisa. Tu consegue dar padrões pra ela seguir? Adotar os padrões da Full Cycle, por exemplo, pra todos os desenvolvimentos que ela gerar? Sim. E ela respeita sempre aquele código? Como se fosse a tua base de conhecimento própria? Sim. Ainda você acrescenta pra ela que se ela não respeitar, você vai pedir pra ela respeitar um ótimo tema pra próxima aula já ia dizer faltando esse tema aí porque assim, vai ser muito útil pra todo mundo aqui, eu tenho certeza ontem o Wesley fez uma live isso aqui teve um incidente ali foi meio conturbado, a gente acabou parando no mesmo caminho mas foi muito bom que ele apresentou ali, eu gostei bastante. Eu tô pesquisando aqui também. Assim, pessoal, até eu vou falar, a gente tá, na última que eu fiz de segurança, de informação, eu tinha pensado algumas coisas, a live foi assim, vocês foram fazendo perguntas, o negócio foi, a gente foi até 11 horas da noite tô gostando assim tipo assim, tem problema sair aqui do assunto vocês que comandam aqui até o meio do ano passado a gente, quando eu falo a gente em termos de quem tá na frente da liderança a gente pensava em IA como out-complete, co-pilot, isso não vai substituir o dev, não tem que se preocupar muito com isso, a IA gera código burro, vai demorar ainda para poder evoluir. Quando nós começamos a conversar com Mercado Livre, Itaú, Newbank, PicPay, Magazine Luiza, conversar com outros empreendedores e ver o que já estava acontecendo, a gente viu que, tipo, a gente já estava para trás, na verdade. Vocês não têm noção do que pessoas não técnicas, não técnicas, elas estão conseguindo desenvolver com o IA, tá? Não técnicas. Pense nisso. Tipo assim, pessoas estão conseguindo gerar negócios, gerando sistemas inteiros, sem ter conhecimento de programação. Isso não é a questão, assim, pra gente poder ficar assustado que ela vai substituir de fato. Mas o ponto, a gente tem que entender, assim, que se você faz uma tarefa robótica, você nunca vai conseguir competir com a IA. A IA sempre vai ser melhor em qualquer tarefa robótica que um ser humano. E é assim que a IA, desde lá da década de 70, né, que esse assunto já existe. Se você pegar a definição ali um pouquinho do assunto de inteligência artificial ela simula a inteligência humana e ela é boa em fazer essas tarefas sequenciais a gente não é bom isso porque a gente dispersa desfoca a gente cansa, a gente é limitado. A IA também tem as suas limitações, mas a IA, ela, tô falando a real, ela não pede férias, ela não precisa de aumento de salário, ela não tem demandas de melhorias de trabalho. É o jogo que a gente tá jogando. Então, assim, desde o ano passado a gente viu que a gente tava errado nesse. Então, assim, desde o ano passado a gente viu que a gente tava errado nesse sentido e começamos a estudar o como agregar a IA tanto na profissão quanto na área de educação. A gente já tá, se não te processa, né? Teve a IA do Cursor aí recentemente que negou fazer o trabalho pra ele. Mas, tipo, a gente vem pensando em como Teve a IA do Cursor aí recentemente que negou fazer o trabalho pra ele. Mas, tipo, a gente vem pensando em como agregar a IA tanto pro desenvolvedor quanto pro ensino. Porque a gente também vai ser afetado. O futuro da educação vai mudar totalmente. A IA, ela vai fazer parte desse processo, não somente pra desenvolvimento, pra área de educação como um todo, graduação, ensino fundamental, ensino básico e tudo mais. Então, a gente vem estudando isso, por isso que a gente tá agregando IA no Full Cycle 4, pra poder mostrar de fato o que é IA de verdade. Não é co-pilot, não é autocomplete. Vai muito mais além, tá? Vai muito mais além. Então fique ligado, assim, muito do que a gente está fazendo no Instagram, acompanhe o canal, acompanhe mesmo os nossos conteúdos, porque a gente vai focar pesado daqui para frente nesse assunto aí. E com certeza a gente pode fazer um encontro trazendo mais informações sobre isso. Pedro Sandrini ia falar alguma coisa? Eu ia falar que, assim, a IA ela é o próximo passo de revolução industrial, né? Que é aquela velha história, da mesma forma que as máquinas substituíram muitas pessoas na revolução industrial em 1800, 1900, não lembro quanto que era, século XIX, né, século XIX, a IA vai substituir muita mão de obra que não tem nem o... Vou além, não é o fundamento. Não tem a facilidade de se comunicar, porque assim, você poder pegar uma regra de negócio e traduzir de maneira que um computador entenda por meio da programação é uma coisa. Agora você traduzir para um ser humano entender e a partir disso uma IA analisar e gerar o seu produto final é totalmente diferente do que você programar. Você só vai literalmente sentar e corrigir o código que foi gerado. Caso haja algum bug, porque assim, do jeito que está evoluindo a coisa, é mais fácil você ter um bug e corrigir o seu código do que ser gerado com algum bug. E a raiva do desenvolvedor é justamente essa, porque a maioria tem visto o IA como o autocomplete, ou ali você pede para ela poder fazer algumas coisas, e aí você vê ela gerando errado e você acha que a IA está nesse estágio. É porque você que está usando de forma errada. Agora, assim, não tenha medo de ser substituído pela IA, sabe por quê? Porque eu acredito que todo mundo que está aqui, por que você não usaria IA no seu ambiente de trabalho? Qual o motivo que está te impedindo de começar a trabalhar com isso se você não começou? Você vai ser substituído por IA se você não usar IA no seu trabalho. É disso que a gente está falando. Quando o desenvolvedor vai ser substituído não é se você está usando IA, tá entendendo, ela tá te gerando resultado. Não é você que a gente tá falando. A gente tá falando é que você tá usando ali um chat EPT, ah, como que eu centralizo uma div? Sei lá, como que eu crio um crude? Crio um crude aí pra mim e me... Isso aí, você tá usando apenas 10% do potencial da IA é esse tipo de profissional que está em negação achando que a IA é somente isso esse profissional, ele pode vir a ser substituído, agora no final das contas, ninguém pode falar isso sabe por que também? tem um gráfico que mostra como que foi a contratação ali na pandemia até 2021 e como que está agora que ele está descendo. Só para vocês poderem ter uma ideia, a gente não voltou ainda a níveis anteriores à pandemia. Então, muito desse cenário de empresas que não estão contratando mais, fecharam vagas e etc., também relacionado a essas posições que não faziam sentido que foram criadas e agora as empresas estão voltando à sobriedade. E acaba também tendo um pouco de IA. Então, no momento, quem fala que a IA vai substituir é a pessoa querendo fazer futurologia não existe, CEOs você vai ver a notícia lá no tech, não sei o que da vida é o CEO falou que vai substituir isso aí ele fala porque no dia seguinte as ações da empresa vão crescer 5% é isso, essas falas servem para isso tem alguma recomendação porque eu vou dizer eu utilizei A e tal só que eu coloco tudo bem bonitinho, tudo bem escrito, como em tese deve ser feito, que tecnologia utilizar só que gera aí eu mancho, acho que tá tudo errado aqui, tem alguma recomendação do que eu posso ler? Do que eu posso... Que vídeo eu posso aprender pra utilizar corretamente a IA? Entendeu? Claro, ela me ajuda demais, demais. Em um arquivo específico. Mas aquele agente que talvez vai gerando vários, entendeu? Tipo, uma lógica, eu quero fazer uma validação de CPF, entendeu? Faço a função aí, ele faz perfeitamente, entendeu? Mas, quando eu coloco mais regra de negócio, quando eu coloco mais contexto pra ele, em toda essa questão, ele não gera de uma maneira satisfatória. E eu vou fazer, porque, né? Tem alguma recomendação de quais vídeos, de qual livro ou algo nesse sentido? Eu vou passar uma recomendação depois de livros e outras coisas que vocês podem ver, tá? Pra não tentar pegar alguma coisa pela metade aqui, mas engenharia de prompt, o pessoal aí tem algumas pessoas que já estão ligadas, né? Estou gostando de ver. Engenharia de prompt não é só, tipo, você entender como que você vai escrever. Estou dando um exemplo de uma metodologia. Você pode criar as tarefas que a IA vai precisar desempenhar, criar tudo isso, e pedir pra uma IA ainda gerar isso de forma adequada para a sua ideia com IA fazer a execução. Então, uma IA gera uma coisa que a outra IA vai fazer. Luiz, vocês estão dando uma olhada no Cooperative Workspace, por acaso? Sim, mas por enquanto a gente está mais focado no Cursor porque o Cursor é o que ainda no momento, porque essa história vira todo momento. O Cursor é a melhor ideia no momento se você quer trabalhar com o IA. Existem várias outras soluções aí, mas a gente está usando também o VS Code Insiders. Se você quer pegar as últimas novidades do VS Code, não use o VS Code normal. Pegue ali a versão Insiders. Você tem atualizações diárias. Você vai amanhecer o dia lá, vai estar o botãozinho pra você poder atualizar de novo a interface já tá bem diferente do S-code normal você tem ali o modo agente, edit e ask no mesmo lugar inline suggestions e outras coisas também, mas a gente tem focado no momento em curso, a gente já testou várias outras soluções, que mais foi legal foi o próprio curso. Mas, assim, existem várias outras. Pode ter certeza que a gente vai produzir muito conteúdo sobre isso. Luiz, é o Augusto. Oi. Oi, Luiz. É o Augusto. Oi. Oi. Eu queria saber se você deu uma olhada essa semana na apresentação da Google Cloud, da nova AI Vertex para grandes infraestruturas, para o mercado de engenharia de software. Eu estive a ver, ainda ontem estive a ver essa nova Vertex é uma outra coisa é astronomo, diferente se eu começar a acreditar que a AI realmente veio para ficar não é aquilo que o conceito que eu tinha anteriormente de que põe, vai no chat de GPT, escreve qualquer coisa, ou numa outra AI e está pronto. Não, é que eu comecei a acreditar a partir dessa apresentação que a Google fez, mudou todo o meu conceito em termos de infraestrutura com AI. Não, eu não cheguei a ver essa apresentação ainda, mas eu já ouvi falar dela. Inclusive, teve outra coisa também com burburinho bastante. É o estúdio com Firebase também que tem IA. A Google entrou meio atrasado nesse contexto e tem recuperado um pouco de mercado. Mas podemos ter certeza. IA veio para ficar. Esse GitHub Workspace, aproveitando que eu estou aqui em aberto é uma das funcionalidades que a GitHub tem desenvolvido imagina que você tem uma issue ou alguma por request com algumas especificações e aí você pede para ela ser solucionada ali pelo próprio GitHub tem também outro projeto que aqui acho que eles não vão mencionar, que é o Padawan, também que está sendo desenvolvido. Enfim, você vai ter muitas soluções. Por isso que a gente deve ficar bem atento. No momento, o Cursor, para poder desenvolver ele mesmo a aplicação, tem sido melhor. para poder desenvolver ele mesmo a aplicação, tem sido melhor. Mas daqui a quatro meses, o VS Code pode ter um crescimento. Pelo que eu tenho percebido, a Microsoft quer pegar esse mercado da Cursor e não sei se vai acontecer ou não. Aí tem que ficar de olho. Esse Copilot Workspace é bem interessante na questão de DevOps pra quem não tem equipe formada ou quem não tem conhecimento porque ele monitora pra ti lá o teu deploy e aí daqui a pouco acontece algumas coisas acontecem, tem falhas então tu tem um agente de ambiente trabalhando por ti e aí tu pode automatizar ele dizendo pra ele o que fazer em alguns cenários e ele também vai guardando como se fossem modelos E aí tu pode automatizar ele, dizendo para ele o que fazer em alguns cenários. E ele também vai guardando, como se fossem modelos, que tu vai dizendo para ele aprender, quando tiver problema assim, faça essa. Quando tiver problema de outra magnitude, trate dessa maneira. Ou busque o conhecimento em tal caminho. E ele vai te ajudando, é bem interessante. Sim, sim. Eu fico imaginando isso aqui também no cenário de open source. Imagina, por exemplo, você tem uma lib bem famosa, que tem lá aquelas trocentas issues para poder resolver os problemas. Para quem mantém código, é muito complicado você atender tudo isso, né? Então imagina uma ferramenta dessa com qualquer desses frameworks, você conseguindo automatizar e resolver esses issues ali em alguns segundos ou alguns minutos, né? Isso é definitivamente fantástico. Então, assim, de soluções de IA, a gente tem várias. A gente não deve se limitar e sempre ficar atento porque a gente só está no começo disso. Daqui a cinco anos, com certeza, tudo isso que a gente está falando aqui dessas ferramentas, eu acredito que vai estar tudo obsoleto isso aqui. Já vai ter mudado radicalmente. Quem que ia falar mais? Uma pergunta rápida. Solaro que estão usando o cursor, mas com qual agente de cloud? Com o cloud 3.4 e 3.7. A gente está testando com os dois. 3.4 e 3.7, beleza. Obrigado. O GPT não tem respondido muito bem, o Cloud tem sido melhor. Acho que isso acaba sendo um consenso também dos desenvolvedores, né, ele tem sido mais adequado pra desenvolvimento. Show de bola, pessoal. Então vamos voltar pra cá, né, a gente daqui a pouco tá falando sobre alguma outra coisa aí, né. Então vamos voltar pra cá, né? A gente daqui a pouco tá falando sobre alguma outra coisa aí, né? Voltando lá pro exemplo do monolito aqui da Full Cycle, o monolito que já tem 11 anos de existência, como eu já disse, ele gerencia toda a parte de ensino e financeiro, então tem a faculdade que a gente é hoje, cursos, provas, vendas, área do aluno, certificados e tudo mais. Aí tem parte de fórum, tinha parte de aulas ao vivo que tinha dentro dele. Na verdade essas partes elas estão lá, mas a gente só desativou o módulo lá para que ele não fique em conflito com algumas outras coisas. conflito com algumas outras coisas. Então tem a área administrativa, que tem a parte visual, mas há a API que serve a área do aluno. Então aquela plataforma que vocês estão vendo ali é um SPA que está consumindo essa aplicação aqui. E essa aplicação atende a mais de 200 mil alunos para as dezenas de cursos, porque como eu falei, a gente já existe desde 2008 então a gente fazia um outro modelo de negócio antes que era criar cursos mais focados, tipo Laravel com alguma coisa, Java com alguma outra coisa assim então já vem atendendo a questões bem mais antigas e agora eu vou falar aqui, mais brevemente, que a gente já gastou um tempo com as dúvidas, sobre esses nove pontos que eu tinha falado aqui sobre essa recuperação do sistema monolítico, e vou falando algumas coisas também que a gente acaba fazendo a implementação. Então, primeira coisa, como identificar problemas no monolito? E a palavra-chave para isso é a observabilidade. Se você não tem isso, essa pergunta aqui, daquele meme, não tem como ser respondida. A minha aplicação está lenta, ou sei lá, está com algum problema. A minha aplicação está lenta, sei lá, está com algum problema. Se você não sabe o que está acontecendo, eu não tenho como te dar o remédio. É a mesma coisa no médico, você chega lá e fala assim, ah, estou com as dores, mas onde está a dor? Ah, não sei. Estou sentindo umas dores aí e tal, né? Não tem como aplicar o remédio. Então, a gente precisa, a gente tem isso na maioria dos nossos treinamentos, a gente fala muito sobre observabilidade, logs, métricas e tracing. Com logs, a gente colhe ali os eventos que estão acontecendo, são os acessos, são os erros. Eu acabei de ver uma aula, gera um login. Acabei de concluir o curso, gera um login. Aí métricas. Quanto de CPU está sendo utilizada as aplicações? Quanto de memória? Quais são as carries mais lentas? Tempo de resposta? Número de vendas? Número de fracasso quando os usuários passam cartão de crédito? E tracing. Quando eu tenho uma comunicação que passa entre uma malha de serviços, eu preciso entender de onde ela veio e por onde ela passou para poder entender não só o problema, mas também para poder colher métricas também de negócio. Então, tracing, métricas e logs são os três pilares principais desse conceito de observabilidade. E tem também, obviamente, os alertas que nós podemos configurar, baseado em tudo isso aqui. Eu posso gerar alertas quando a minha aplicação está lenta, quando as métricas não estão dentro dos parâmetros, quando as aplicações estão indisponíveis, aí esses alertas podem ser relatórios, envios de e-mail, mensagem no Slack, mensagem no WhatsApp, enfim. Hoje a Fullcycle utiliza o New Relic e o UpTime. Na verdade a gente acaba utilizando um pouco o Grafana e Prometheus, mas é algo mais restrito. Mas a New Relic, que é uma plataforma que já existe há muito tempo, não é, eu não estou fazendo merchan dela, inclusive não estou ganhando nada, mas é uma ferramenta que já traz tudo, como outras também, Datadog, Dynatrace, enfim, tem várias outras. Dynatrace enfim, tem várias outras, mas o New Relic é muito fácil fazer integração com qualquer tipo de aplicação, tem lá os agentes que ficam monitorando as coisas da aplicação, então a gente gerencia tudo por aqui se você tem observabilidade você sabe o que está acontecendo então isso é o primeiro passo para que você mantenha bem o seu monolito e consegue ir recuperando ele, caso ele esteja com problemas. Agora, o segundo assunto é testes. Testes é assunto tarimbado. No final das contas, mesmo que você use, você não gosta. Inclusive, a gente olha muito pelos parâmetros dos conteúdos quando a gente produz conteúdo se eu fizer na próxima semana uma live aqui com você, só falando de testes, eu tenho certeza que vai aparecer 20 pessoas aqui se eu fizer um conteúdo de testes e publicar no YouTube vai dar lá umas duas mil visualizações a gente já tem essa experiência normalmente o desenvolvedor não gosta de testes, acha teste algo que é desnecessário uma obrigação que você tem que fazer que enfim, de alguma forma alguém deveria estripar isso do desenvolvimento, tá? Se falar de IA, então, até minha mãe vai vir me assistir. É, a IA, a gente delega tudo, os testes todos pra ela, né? O trabalho todo pesado. Ah, fiz, ou eu fiz aqui, eu pedi pra você poder fazer. Agora testa esse negócio aí, arruma as formas de fazer, não é assim? Teste é algo que a gente não quer. No início dessa nossa aplicação, tinha testes, tá? Tinha testes. Inclusive, nesse início aqui, eu nem trabalhava com o Wesley ainda. O Wesley foi o criador dos primeiros testes. Ele foi a primeira pessoa que criou essa aplicação, mas não tinha no CI. Aí aquela história, pô, tipo, você tem testes, mas não é obrigado a executar. Então não adianta muita coisa. Quando a empresa foi crescendo, criou-se um incentivo pra fazer qualquer coisa sem testes. A desculpa é sempre o tempo, né? Não, que a gente tem que entregar isso aqui e depois testa. Aí o que que isso acumulou? Um amontoado de dívida técnica. Você vai deixando sempre para depois. Aí chegou um ponto que todo deploy tinha um problema a ser corrigido, gerava estresse entre o Wesley, eu, os desenvolvedores e as outras áreas que a gente tem dentro da empresa. E tinha vários motivos pelo qual esses testes também que rodavam, estavam quebrando, eles não eram atualizados, a aplicação foi mudando, e acabou que a gente começou a fazer alguns testes novamente. E aí é uma pergunta que eu recebo muito, a minha aplicação não tem testes ou tem poucos testes, como que eu consigo adequá-la? A empresa não vai ter o ano sabático para você poder testar, tá? Eu recebo muito esse feedback dos alunos, mas poxa, a gente não vai parar para poder testar, tá? Eu recebo muito esse feedback dos alunos, mas poxa, a gente não vai parar pra poder testar, né? Seria o ideal. É, a empresa não vai deixar de faturar que você quer testar a aplicação. Ela tem que continuar faturando pra poder pagar o seu salário. É o que o software tá entregando é que tá pagando aí o leite das crianças, né? Então, o que começou a acontecer? vários testes foram sendo criados a gente usou a estratégia lá do Clean Code do Robert Martin que é a estratégia do escoteiro Robert Martin fala no Clean Code que em software, independente seja para testes ou não sempre quando você vai num lugar e faz alguma mudança você tem o dever de deixar aquele lugar mais limpo, porque o escoteiro faz assim quando ele acampa num lugar ele tem que dever de deixar o lugar mais limpo desde quando ele chegou lá, então em software também é assim, fazendo dessa forma a gente vai de grão em grão. Ah, então eu mexi naquela área ali, posso criar um teste de unidade que é mais simples. Aí, ao longo do tempo, esses testes vão segregando e nós temos mais cobertura e confiança. Porque teste é a chave para qualquer aplicação, seja monolítica ou de microserviços, poder funcionar bem. É a primeira garantia que a gente tem. Mas aí aconteceu outro problema. Os testes estavam demorando 33 minutos só para poder rodar no CI. Aí que isso se duplica porque a gente tem ambiente de homologação e ambiente de produção. Então, demorava 33 minutos para poder rodar na homologação e 33 minutos para poder rodar em produção. Se você fez tudo certo de primeira, você vai gastar no mínimo uma hora. Isso aqui era um problemaço, né? O desenvolvedor podia ir tomar um café, almoçar, fazer alguma coisa assim e deixar isso aqui rodando, né? Porque isso aqui era um problemaço. Eles chegavam a gastar 5 gigas pra poder rodar esses testes. A gente teve que pagar muito GitHub Action, porque GitHub Action, se eu não me engano, são 3 mil minutos, alguma coisa assim que você tem por mês ali no plano. É 2 mil. É 2 mil? Se você baixa isso aí... É baixar para 2 mil? Aí ele começa a te cobrar por minuto rodado. E não era só essa aplicação que a gente tinha. Então, isso aqui começou a não só tornar inviável também, olha só, estou testando, mas os testes não estão performáticos, começou a tornar inviável produzir coisas nessa aplicação, porque todo deploy era um parto, e começou a aumentar o custo. Então, a gente já tinha implementado essa regra do escoteiro para poder melhorar os testes, mas nós melhoramos também a nossa esteira de CI, que de um certo tempo os testes eram obrigatórios. Nós reescrevemos toda a base de testes com o PHP Unity do kernel do Symfony justamente para poder melhorar esses 33 minutos aqui. E talvez você possa se perguntar, mas esse tempo aqui não é porque vocês estão usando o banco de dados como o banco de dados real ali para poder fazer esses testes? Na verdade, eram vários tipos de problemas. O próprio PHP é um, porque o PHP nessa versão, mesmo 7, apesar dele ter sido otimizado, em comparação com o PHP 7.4, o 7.1 é muito lento. A versão 8 é muito mais rápida, então a gente teve que fazer várias mudanças ali em nível de código do PHP 1, o kernel do Symfony, e os testes já rodavam com o SQLite em memória. E pasmem, a gente roda com o SQLite em arquivo pra poder ficar mais rápido, usando o Docker TempoFS, que cria um diretório temporário em memória, porque quando a gente usava em memória, se eu rodasse testes em paralelos, o Symfony com a biblioteca dele lá de banco de dados, demorava muito pra poder carregar os dados. Então mesmo em memória era ruim porque cada teste levantava um novo banco. Então não adiantava você colocar em memória. Então a gente colocou em arquivo, porque aí eu gero sempre um backup dos dados ali de teste mas aí jogando com docker tempfs eu jogo tudo pra memória de qualquer forma então é arquivo mas não é então tá vendo que determinadas soluções é você entender o contexto ali e encontrar uma ferramenta que vai ser bacana antes a gente não usava testes em paralelo, agora a gente roda apenas com duas instâncias, gasta apenas 4 minutos e 500 MB. E esses 500 MB aqui, por aplicação do tamanho que ela é e por conta do PHP, que consome muita memória, já tá de bom tamanho, né? Então foi um processo muito importante para a gente poder garantir esse monolito aqui. Tudo que a gente faz tem que ser devidamente testado, tem que ter cobertura de testes. O teste tem que estar muito bem feito. Ele tem que estar com grande performance. Sobre linguagem de programação e framework. Oi. Luiz, desculpa interromper, uma dúvida. Não sei se os senhores tinham migrations desde o início do projeto. Desde o início. Desde o início. Pois existe um problema ali, quando vai começar a implementar a teste, a gente tem um banco todo já construído ali, sem usar migrations. A gente nunca usou migrations para construir o banco de testes. Sempre foi pegando o próprio mapeamento do ORM. Aí constrói a parte do banco ali relativa àquela parte que vai ser testada. Somente aquela parte ali. Como é que funciona isso? Funciona assim, ó. O PHP hoje, na verdade Com a versão 8 Ele tem um suporte nativo a decorator Esse padrão aí que existe no JavaScript, no Java, no C Sharp O PHP, ele usava Uma gambiarra, que era você fazer Um comentário com Duplo asterisco E aí você colocava Os arrobas lá com as coisas e aí que é o problema, quando você carrega um comentário você tem que ler muito o código pra poder fazer todo o mapeamento e depois fazer ali a geração desse SQL então essa versão do Symf não permitia que um SQLite memória fosse compartilhado, não dava, se eu rodasse teste em paralelo não adiantava, então rodado o teste, ele levantar isso aí tinha um custo muito alto de tempo pra poder fazer essa, porque eram muitas entidades, a gente tem muitas entidades, então a gente sempre tem um backup, uma instância do SQLite já com esse mapeamento feito em file, que todo teste ele pega aquela instância, se eu rodar 10 em paralelo, ele vai pegar aquela instânciazinha ali do file do SQLite, que tá em memória por causa do docker, e aí ele executa entendeu? hoje, o PHP com a Notation é muito mais rápido, porque é algo nativo da própria linguagem. Da versão 8 para trás não era. Então, são questões que você tem que saber contornar. Sobre linguagem de programação e framework, é algo importante, porque muitas vezes a gente despreza que atualizar a linguagem ou o framework pode resolver muitos problemas. Quando a gente estava na versão 5, a gente chegou a utilizar DigitalOcean. Nessa época não tinha Docker, não tinha Kubernetes. Oi. Só antes de você ir para esse próximo assunto, falando um pouco de testes e aproveitando o bate-papo ali de IA, como que a IA está em relação a testes? Vocês costumam pedir testes para IA ou o teste é um negócio que fica mais focado em vocês mesmos? Daria para confiar nos testes da IA? Essa aplicação é um exemplo legal, porque principalmente nessa parte do PHP, nessa época, imagina que você está criando um teste de integração, mas você quer fazer um mock de alguns serviços que você tem que estar envolvido e que você não quer testar. Isso é muito difícil com PHP, é muito. Tipo assim, em comparação com o JavaScript da vida, que você pega qualquer objeto ali, cria um mock e vai passando, isso é um parto. Muitas vezes você demora minutos para poder fazer esse mock até você conseguir gerar esse teste. Então, a gente já tem uma base de treinamento em como criar esses mocks, por exemplo, então torna muito mais fácil fazer esses testes porque eu posso chegar e falar assim, ó, estou fazendo esse teste aqui relativo à compra do curso. Então, eu quero que você crie os mocks baseado nessa estrutura que você já tem para poder isolar o gate de pagamento, o envio do e-mail e algumas outras coisas. Então, prepare aqui um ambiente em que o aluno vai passar um cartão em que as informações estão inválidas. Antes, se eu não usasse A, eu demoraria muito tempo pra poder fazer esse teste. É muito tempo, tá? É muito chato. É muito chato. Nossos devs reclamavam muito dessa questão. Porque hoje a gente já tem muito mais ferramentas para poder ajudar nisso. O próprio HP Unity é muito chato para poder criar esses mocs, mas a gente acaba usando uma ferramenta chamada de... Acho que é mockery. Mockery, ou algo assim. Mockery, essa aqui, ó. A gente usa essa ferramenta que ajuda um pouco mais, mas por conta que a aplicação é antiga, tem que usar uma versão antiga da biblioteca, então várias novidades não estão presentes para poder ajudar. Você não tem noção de como é chato gerar mock em aplicação antiga PHP isso quando você acha que você gerou um mock correto, aí o seu teste não passa e você tem que ficar uma hora fazendo o debugging pra poder entender que é o seu mock que tá errado entende? Então você perde muito tempo, é tempo que você tá gastando ali que você deveria estar fazendo outras coisas Então, vocês usam mais pra mocs mesmo não, tipo assim, ó, tem esse gate, o agente de pagamento cria os testes pra ele A gente gera os casos em muitas situações a gente gera um contexto muito bem delimitado dado ali os cenários ações, a gente gera um contexto muito bem delimitado, dado ali os cenários. A gente utiliza um pouco do BDD para poder criar esses cenários, não que a gente utiliza BDD na implementação do código, mas é porque o BDD você é orientado a trabalhar com os testes ou pensar neles em comportamentos, ao invés das funcionalidades em si. Então, por exemplo, nesse cenário das compras, eu tenho que fazer testes passando dados inválidos, tentando fazer alguma coisa da autenticação, que inclusive a nossa autenticação antes era um problema, então tinha dois modos de trabalhar, não lembro exatamente agora de cabeça. Então a gente cria esses cenários e pede também para ela poder fazer a execução. Mas sempre a gente confere os testes. É muito, assim, mesmo que demore um pouco mais pra poder conferir, mas reduziu muito o tempo. A gente pede sim pra poder gerar os testes. A gente pede, na verdade, hoje a gente tem mais pedido pra poder gerar os testes do que gerar o teste do zero. Beleza. Também porque a gente já tem uma base grande de testes. Pelo que eu estou entendendo também, vocês têm uma documentação boa, né? Quando você falou que vai integrar com o terceiro, vocês pedem elas para gerar as informações. Você precisaria de uma documentação para conseguir passar para ela e ela gerar os dados através disso. Sim, sim. E a gente era muito fraco nisso, porque a gente é uma empresa pequena, pessoal. A gente tem nem 100 colaboradores. A gente é uma empresa educacional pequena que foi crescendo ao longo do tempo. Então, aquela ideia de startup, você tem X pessoas, mas aquelas X pessoas fazem um trabalho, conseguem produzir trabalho de 10. Toda startup é assim, né. Você tem um nicho ali de pessoas e elas fazem muito mais às vezes do que pessoas que estão em empresas maiores. E as coisas foram crescendo de certo modo, né, que chegou um ponto que tinha que um ponto que tinha que ver como funcionava a venda a gente não tinha que perguntar pra mim, tinha que perguntar pro Wesley tinha que perguntar pro nosso tech lead entende o que isso acaba gerando? então documentação é algo importante. A gente cuidou bastante disso nos últimos cinco anos porque a gente estava tendo muitos problemas. Eram muitas falhas de comunicação, porque se achava que a coisa funcionava de uma certa forma, aí você implementava ali o que era necessário, depois aquilo voltava ou ia para a produção de forma errada, e acabava gerando outros problemas. Tudo porque você não tinha uma base de conhecimento do que estava sendo feito. Então, voltando aqui... Qual a ferramenta que os senhores usaram Para documentar O próprio Markdown No código mesmo A gente usa só o Markdown A gente usa só o Markdown Tem alguns de H1C4 Para algumas coisas Mas como a nossa infra Não é algo complexo Não há necessidade disso É mais o Markdown porque É importante Não é algo complexo. Não há necessidade disso. É mais o Markdown porque é importante com o Markdown você manter o histórico das motivações do que vai sendo feito ao longo do tempo. Você depois consegue ver essas decisões foram tomadas e tal. Esse cenário funciona exatamente dessa forma. Está sendo usado essas tecnologias aqui. Porque Markdown é muito bom para fazer histórico, você faz change logs a cada mudança que vai acontecendo agora para você poder ter uma visão panorâmica enxergar a comunicação com outros sistemas aí diagramas são muito melhores Luiz, só uma pode falar. Luiz, só uma... Luiz? Estou te ouvindo, Luciano. Eu tenho uma dúvida lá em uma empresa que a gente tem uma plataforma de PHP própria e a gente está pensando em trocar para um framework de mercado, seria ou o Symfony ou o Laravel. Eu vi aí que vocês escolheram o Symfony. Algum motivo especial, alguma coisa... O que você pode falar para me ajudar aí? Lá atrás, nesse ano de 2013, deixa eu até pesquisar aqui o ano que o Laravel foi lançado. Laravel foi lançado em que ano? Laravel foi lançado em 2011, tá? Nessa época que provavelmente, quando foi criado aqui esse projeto, o Laravel devia estar na versão 2 talvez 3 e nessa época o Laravel nem usava o Symfony, porque hoje toda a base ali de foundation e tal do Laravel é Symfony, né tem até uma entrevista que a gente fez há muito tempo atrás com o Taylor Ott que é o criador do Laravel, ele fala assim pô, tava puto porque mexendo com as rotas, essas configurações de baixo nível ali do framework davam trabalho, quebravam e tudo mais. O Symfony ele fala, o Symfony é o melhor framework PHP e a gente acabou utilizando. Então, nessa época aqui, a gente queria um framework que já trouxesse uma bagagem de trazer autenticação, validação, área administrativa e coisas assim. Então a gente escolheu o Symfony exatamente por conta disso e também nessa época aqui, porque o background do Wesley, eu não participei do início do projeto, o background do Wesley era trabalhar com Python e PHP. Ele tinha conhecimento com .NET, mas era bastante ferrujado, ele estava focando bastante em PHP. Então foi uma decisão que na época a empresa só tinha quatro pessoas. Não, era uma decisão difícil de tomar, não tinha briga tecnológica, você escolhe o que você tinha à disposição. Entendeu? Exatamente por isso. Nenhum motivo especial. Poderia até ter escolhido na verdade, até uma provocação pro Wesley, poderia ter escolhido o Zend. Porque já o Zend aqui nessa época competia ali com o Symfony pra ver quem que era o melhor framework. Mas o lance do Zend framework era que você não tinha muitas coisas já embutidas nele, como o RGM você tinha que importar o Symfony já trazia o Doctrine você tinha até uma organização ali em questão de módulos container de serviços mas isso o Symfony já tem então o Symfony é muito mais dinâmico acabou que o Zend Framework morreu foi lá pra Linux Foundation virou Laminas E de Laminas virou DotCard Não sei se vocês estão acompanhando E morreu Tipo assim, tá ainda ativo Mas o projeto literalmente morreu O Symfony continua de pé E o Laravel continua utilizando ele Nessa época aqui do PHP 5 Nós rodamos essa aplicação Inicialmente eu não lembro se teve alguma outra hospedagem em algum outro lugar, mas eu lembro que a gente fazia um deploy via Git na DigitalOcean isso aqui era o PHP 5 na época então, estava tudo bem, fazia ali um Git push, as coisas aconteciam, nessa época não tinha CI isso aqui era o PHP 5 na época então estava tudo bem, fazia ali um git push, as coisas aconteciam, nessa época não tinha CI, aí depois nós migramos pra Heroku não sei se vocês conhecem a Heroku foi a primeira cloud, na verdade a espelhar um pouco do que como funciona a Docker, você fazia ali um git push ele criava como se fosse um container da sua aplicação sem que você se preocupasse com infraestrutura nenhuma né e depois do heroku começou a ficar caro ali para poder fazer o escalonamento que aplicação estava consumindo recursos necessários nós somos para o cloud depois voltamos para a Heroku de novo, e aí tomamos uma decisão. Não, agora vamos mexer com container. Ah não, vamos colocar que container isso era por volta de 2017, eu acho. Por aí. Quando colocamos a aplicação em container, a aplicação não parava de pé. Por que que não parava de pé? Porque ela tinha um consumo muito desnecessário de recursos tanto de CPU quanto de memória, por causa do PHP 5 PHP 5 era assim em termos de performance comparado com outras linguagens é um desastre e aí o que que nós resolvemos fazer? vamos migrar para 7.1? migramos a aplicação deixou de consumir vamos fazer? Vamos migrar para 7.1? Migramos. A aplicação deixou de consumir 60% do que ela consumia antes. Só migrando linguagem de programação. Olha que interessante. Tinha vários outros problemas, mas a questão justamente era a linguagem ali que estava atravancando o negócio. Então, atualização de linguagem, não subestime ela, porque nesse caso aqui, o PHP 7, a gente sabia que a Intel entrou em conjunto ali com a comunidade do PHP e remodelou o PHP totalmente. Então, PHP 7 ou PHP 5, por isso que não tem o PHP 6, né? O PHP 6 é até uma história de um mito, né? Tem livros que você vai encontrar aí PHP 6 alguma coisa assim, tem gente que já se antecipou e essa versão nunca foi criada acabou indo pro 7 A gente projeta em migração A migração foi tranquila? Migração? É, foi tranquila? A migração... É, foi tranquila? A migração não foi tão tranquila, porque nós tivemos que mudar vários pontos da aplicação que o Symfony não suportava. Mas não foi catastrófico. Algo que a gente gastou, sei lá, dois, três dias. Não foi algo complicado de fazer por que a gente não foi PHP 8? porque o Symfony só dava pra poder atualizar sem quebrar o projeto inteiro até a versão 2.8, a gente começou 2.5 na verdade foi até 2.8 acontece que se a gente migrar pra 3.0 que é a próxima versão aí vai ser necessário usar obrigatoriamente 7.2 do PHP que vai quebrar uma série de coisas então assim, a gente atualizou até onde dá mas a gente projeta em atualizar para 7.2 se dá para atualizar para 7.2, dá para atualizar para 7.4 só isso aqui também já vai tornar a aplicação muito mais rápida então pense nisso, muitas vezes você pode ter o seu legado aí e essas atualizações até onde der se forem planejadas elas fazem total diferença tá aí dessa parte aqui de atualização de configurações, eu já falei da versão antiga. Quando migrar, por exemplo, quando a versão ficar estável e já estiver rodando bem no mercado? Migrar, você fala de... para uma nova linguagem? Uma versão da linguagem? Exato. Ah, tá. A gente planeja porque, assim, a versão 7.1, ela... Não, não, não. O que eu digo é o seguinte. Ah, saiu 8 hoje. Você já planeja ou você tem... Você planeja e vê o mercado como ele está se comportando? Qual é a sua ideia? Ah, de como pensar essa migração, eu acho que surgir uma nova linguagem e você já migrar para ela é um cenário utópico, porque se você já puder fazer isso, estou dando um exemplo de um Django framework que é outro framework que a gente tem aqui dentro. A gente tem um Django 2. Dá para migrar para o 4? Provavelmente dá, porque o próprio framework quase não muda nada. Então, nesse cenário, você me lê muito bom, porque você já pode usar bibliotecas mais novas, dá para atualizar a versão de Python, então você vai economizar CPU, vai economizar memória, vai melhorar a tipagem ali, porque o Python, ultimamente, melhorou bastante a questão dos typings dele. Então, eu vejo que, se ela vai trazer benefício técnico e não vai ser difícil de fazer, não vejo por que não fazer Agora Se você vai demorar muito tempo Pra isso, com um risco bem grande Você vai ter que ficar semanas Aí isso tem que ser planejado É o que a gente tá fazendo aqui A gente tá adiando esse momento Porque essa migração aqui Só pra essa 7.2 Ela já vai quebrar tantas coisas dentro do Symfony, fora as bibliotecas, que a gente já tentou, pra vocês terem ideia com o QIA, eu vou contar aqui o caso. A gente pensou assim, poxa, isso aqui é uma necessidade que a gente tem. A gente pegou o Cursor e o Devin, eles não conseguiram fazer. A gente entregou essa tarefa para a IA, não conseguiu. Curiosidade aqui, Luiz. Como é que vocês planejam essa questão de atualização? Eu nunca passei ainda por esse processo. Na empresa onde eu trabalho, a gente os novos sistemas a gente já cria na última versão, inclusive só que um sistema legado, por exemplo, na versão 7.2 ou 7.3 do PHP. Mas como é o processo de migração? Tem alguma ferramenta que vocês indicam utilizar? Como é essa questão de planejamento também? Assim, em questão de ferramentas, a primeira coisa que você tem que ter é testes. É o primeiro princípio aqui. Na verdade, o segundo. Testes. por quê? se você fez a migração agora, como que você vai garantir que as principais partes do software principalmente estão funcionando você vai testar na mão? manual? você não vai ter você não vai testar todos os casos, sempre vai sobrar um caso específico, que aquele caso quando estiver lá em produção, nossa, agora a gente vai ter que ficar fazendo hora extra aqui pra poder corrigir. Então é testes. O primeiro ponto é testes. Tá? Somente com isso que você vai conseguir ter essa garantia. Agora, em questão de outras ferramentas, pro caso do PHP, você pode utilizar PHP Code Sniffer tem tempo que eu não mexo com PHP Code Sniffer, tem outras ferramentas também que vão te ajudar ali a fazer várias verificações de coisas que você tem que mudar, porque eles analisam a linguagem então eles vão olhar essa parte do código aqui tá errada, você tem que fazer a mudança, então eles vão olhar essa parte do código aqui está errada, você tem que fazer a mudança, então tem algumas ferramentas aí da própria comunidade que você pode agregar nesse processo. Mas um dos principais problemas para o PHP nesse caso é o Composer, que é o Composer mais antigo, ele demora muito tempo para rodar e os erros que ele reverte ali quando você tá atualizando as bibliotecas, não é muito sugestivo apesar que a IA agora ajuda, né você tenta atualizar ah, tô atualizando o Doctrine aí ele quebra em vários outros lugares aí lugares são circulares e você fica meio sem saber o que que acontece que é o ponto da IA a IA se confunde. Porque a gente tem um Docker Compose imenso de bibliotecas. Até coisa de Zenit e Premiere que a gente tem dentro dessa aplicação. Então, tem que estudar muito bem essa questão das novas versões que têm que ser atualizadas. Você tem que, pelo menos, chegar até a última versão de cada lib pra poder te ajudar a migrar pras próximas porque vamos supor assim, você tá com a versão bem desatual dessa lib tenta atualizar até onde der no momento que você tá, porque pra próxima versão que você vai atualizar, facilita muito mais pra você poder buscar quais são as próximas versões esse trabalho, nesse caso é trabalho de formiguinha você tem que ir em muitos GitHub das bibliotecas fazer a análise das dependências entender quais vão ser as próximas versões e fazer uma atualização e ir tentando com Composer. A gente tentou isso aqui durante dias com IA, a IA não conseguiu fazer. Ela começava a atualizar, quebrava um ponto, aí ela resolvia, ia para o próximo, aí quebrava o anterior de novo por conta de uma versão de alguma outra lib. Porque não é um trabalho... Se nem a IA está dando conta aí vem a questão da experiência nossa é porque a gente sabe aqui que uma migração como essa vai gastar semanas é por isso que a gente pediu para a IA fazer a gente não fez até agora, senão já estava pronto então, o planejamento disso você está querendo saber como que a empresa vai se planejar para poder fazer essa migração ou como que você planeja a própria migração eu acho que você já respondeu aí o intuito a minha pergunta em si lá a gente tem um sistema hoje a gente está em um âmbito de fábrica de software a gente tem vários softwares que a gente já cria com boas práticas, seguindo testes, documentações, etc. Só que é um sistema específico, ele está com um PHP antigo, não tem testes, e a gente já pensou em atualizar, mas nunca chegou a executar. Mas eu acho que sem possibilidades. Não, não. Tipo assim, isso já é totalmente descartado, não tem nem que conversar essa migração, ela vai acontecer, ah, você pode você e os seus colegas podem fazer um trabalho incrível de virar a noite e fazer essa migração mas vocês vão se arrepender porque vão acontecer um monte de coisas inesperadas e vocês vão se arrepender. Porque vão acontecer um monte de coisas inesperadas e vocês vão ter que resolver. A culpa vai ser de vocês. Então, testes é o primeiro ponto. Luiz, posso fazer uma outra pergunta? Posso fazer uma pergunta? Como é que vocês lidam com a questão de segurança e vulnerabilidade? Porque, pelo que eu entendi ali, vocês estão usando A versão 7.1 do PHP hoje, né E pretendem migrar para a 7.1, não é isso? E a versão 7.1 já foi depreciada Já tem bastante tempo, como é que vocês lidam Com essa questão? A gente foca mais nas libs, esse ponto que eu estou Colocando aqui, vamos supor que Tem alguma O PHP 7.1 obviamente tem as vulnerabilidades ali, mas a gente se preocupa em proteger, baseado, por exemplo, no New Relic, que é uma ferramenta que ajuda muito a resolver esses problemas, a gente vai fazendo forks. Então, o PHP a gente não pode resolver, mas as libs que vão tendo as vulnerabilidades, a gente tem no nosso GitHub vários forks pra quando vai instalar a lib, instalar a nossa modificada corrigida com o que a gente colocou. Então a gente vai fazendo, vai mantendo esses forks. Ah, entendi. Beleza. O PHP mesmo não tem o que fazer. Se ele tem vulnerabilidade, eu não posso mudar a linguagem. Mas as bibliotecas, sim eu consigo mudar infinitamente até quando fizer sentido também, né, obviamente beleza banco de dados, cache HTTP isso na verdade a gente já estava falando lá atrás, né a performance da aplicação é medida pelo suelo mais fraco não adianta nada ter uma aplicação com Golang, com Rust, com Elixir, com a linguagem mais veloz, sendo que ela faz uma chamada HTTP, ela comunica com o cache ou ela comunica com o banco de dados. É isso, basicamente, que faz as nossas aplicações gargalarem, né? Fora a questão da má implementação. Então, em questão de banco de dados, problemas comuns que a gente deve se preocupar. Normalização excessiva, que é a pergunta do Henrique. Eu não sei se é o Henrique Rocha, mas tinha um outro Henrique aqui. Não sei se ele está aí ainda. Se estiver, manda um oi. Tem um Henrique. Tem outro Henrique aqui. Ah, então o Henrique aí, ó. Está aqui, Henrique. Está aqui um dos principais problemas. A gente tem que lembrar hoje, armazenamento é barato. Tinha alguém aqui que falou que, ah, você já trabalha há bastante tempo na profissão, eu sei o quanto que era, é caro, né, armazenamento. Armazenamento hoje é barato. Então, essa normalização, não, eu não posso duplicar dado, isso aqui era neurótico lá naquela época. Hoje nós não devemos nos preocupar em duplicar esses dados, porque nós vamos ter esses benefícios de tornar a recuperação dessas informações de forma muito mais rápida e utilizando menos recursos. Então, lembre-se disso. No caso, estude bastante normalização porque tem também primeira forma normal, segunda forma normal, várias formas de você fazer desnormalização, se for banco de dados no Ciclo também, aí você consegue fazer uma desnormalização bem bacana, enfim. Mal uso dos índices e aqui não é só você não criar índices, e aqui não é só você não criar índices para as suas consultas, tá? Porque muitas pessoas acabam criando os índices e mesmo assim isso não tem influência. Determinados bancos de dados, eles têm vários tipos de índices e o modo como você cria esses índices, que muda como o banco de dados vai fazer a recuperação e análise dos registros, tá? Vou dar o exemplo do próprio Postgres. Tem muitos modos de como você vai criar os índices, não é só a junção das colunas e ponto final. Então, dê uma estudada nisso, olhe quais são as colunas que são necessárias na hora de fazer a pesquisa, veja qual o tipo de índice mais adequado e crie os índices de forma correta, porque pode deixar mais lento. Às vezes é isso, você cria os índices ali e aí você endói do banco de dados e ele vai deixar mais lento do que estava antes. Mal uso de conexões também é outro problema. Tá? A gente tem que lembrar que banco de dados não tem conexão infinita. Muitas aplicações acabam criando uma conexão para cada chamada. Você tem que trabalhar com o pool de conexões, o pool de conexões não tem uma resposta definitiva, ele é baseado no número de cores, eu tenho um cálculo que você usa o número de cores da máquina para poder ver quantos pools de conexões você precisa. Pool de conexão, você vai ter ali uma malha de conexões você precisa Pools de conexão Você vai ter ali uma malha de conexões Que elas são reaproveitadas Entre as chamadas que são feitas Então são criadas novas conexões Que faz com que o banco de dados não sufoque Olha isso Muitas vezes você pode ter um pool de conexões Na sua aplicação, mas em um determinado lugar Não está sendo utilizado Já vi muita empresa assim. Às vezes a empresa nem sabia que ela não estava usando o pool. Ou que determinado lugar lá era o que era o gargalo que não tinha o pool, que ela estava usando o pool em outros lugares. Então dê uma olhada nisso. Vai ter limite de conexão e isso aqui impacta no banco de dados. E muitas vezes o banco de dados faz milagre. Eu já vi banco de dados que suporta no máximo 200 conexões, 500 conexões em mil, ele tá suportando duas vezes mais, né? O banco de dados tá ali no... Me salve, pelo amor de Deus, mas ele tá fazendo o trabalho dele. Então, cuidado com isso. Jogue no caching. Cuidado com isso aqui também, porque muitas vezes o seu próprio banco de dados pode trabalhar como cache. Ele pode ser tão rápido quanto um Redis da vida. Então analise isso. Bancos de dados como Postgres ou Aurora da vida permitem que você coloque essas informações no cache. Uso demasiado do ORM também é outro problema. O uso demasiado do ORM também é outro problema. ORMs são muito bons, porque abstrai complexidade, abstrai SQL, mas você tem que saber como utilizá-los, saber as carries que estão sendo geradas. Muitas vezes a gente delega tudo o poder para ele, e ele vai fazer muitas carries necessárias. Procure saber qual a diferença de aggro loading com lazy loading. Entender se ele está gerando carries a mais. Às vezes, duas carries a mais, agregada pelo número de usuários que estão acessando, gera um problema no seu banco de dados. Muitas vezes, criar a carry na mão pode ser melhor. Se você está gerando relatórios vai fazer muitos joins com certeza criar a carry do zero vai ser muito melhor que deixar o rm fazer carry how é o melhor caso que você tem para performance tipos de dados inadequados quando você está usando uma chave primária como string, você está usando isso de forma errada no seu banco de dados. Se você tem um UUID que ele é a chave primária, isso impacta na performance. Se você tem que usar um UUID, tente buscar um tipo adequado do banco de dados para isso, coloque uma chave primária ou uma chave adequada do banco e deixe o UID como unique. Procure isso. Chaves primárias têm que ser tipos recomendados dos bancos de dados. Isso afeta incrivelmente a performance que a gente imagina. Então procure ver se você tem alguns outros dados, às vezes eu tenho um dado que eu tenho que armazenar só 40 caracteres, mas eu tenho um campo de texto infinito. Isso também afeta a performance, fora a questão de armazenamento. Usar NoSQL como resposta imediata. Tem muitas empresas que fizeram isso lá ali nos anos 2016, 2017, né, com o... principalmente aí, quem é da época que tinha lá o... vou colocar aqui no chat, o Min e o... como é que é o Minvi? Acho que era assim, você trocava o Angular por o Vue.js. Mongo, Express, Angular e Node. Aí se você tirar o Angular e colocar o Vue, aí muda que é a sigla. Mas nessa época se pensou que agora o futuro é NoSQL e tudo mais. Não é bem assim que funciona. Bancos NoSQL tem uma outra pegada, normalmente, se você nunca trabalhou, a dinâmica é bem diferente na hora de fazer queries agregadas, na hora de juntar, contabilizar informações. Às vezes pode tornar mais caro e trazer mais insegurança, porque muitos bancos de dados no CICOM não trabalham com consistência como bancos de dados tradicionais, não trabalha com integridade referencial, isso pode fazer com que você gere dados inconsistentes, acabando com o seu negócio. Então, às vezes, a empresa toma essa decisão de colocar ali as consultas replicando para NoSQL, mas essa tem que ser uma decisão muito bem pensada. O mau uso também de locking e concurrence. Nós temos vários tipos, várias formas de lidar com transações concorrentes. Você tem locks otimistas, locks pessimistas. Todos eles têm vantagens e desvantagens bancos de dados como o Postgres tem 13 tipos de locks na hora que você vai fazer também uma transaction que vai envolver isso aí pra poder consolidar várias transações você tem vários modos de consultar alguma coisa que está dentro do escopo da transação read committed e outros tipos também, então entenda qual é o cenário que cabe no seu contexto, porque quando você faz um lock você prende ali a tabela ou registro, fazendo com que o banco de dados consuma mais recursos, fazendo com que outras transações fiquem esperando para poder executar. Isso pode quebrar a sua aplicação e quebrar o banco de dados também. Então, em cenários que você tem muitas transações que podem ficar esperando pra poder executar um lock pessimista que trava tecnicamente o banco, não é legal seria melhor um otimista otimista, ele não trava o banco de dados mas também você pode ter várias retentativas ele trabalha com versionamento de registro então ele é mais permissivo então, olha exatamente se você não tem Isso aqui que está travando Porque eu já vi muita empresa com os problemas de lock Também mal gerenciados E não utilizar Estratégias de sincronização De dados também Com os seus Bancos de dados Sobre cache Sobe um cache aí Usar cache logo de cara bancos de dados, tá? Sobre cache, sobe um cache aí. Usar cache logo de cara vira um santo graal pra resolução de problemas. Cache por si só... Oi? Tem uma questão, né? Eu uso hoje o RDS Aurora, né, com service, né? Então eu tenho a réplica descrita e algumas réplicas de leitura, né? Eu tenho dados que eu preciso gravar e ler ele em tempo real gravar e consultar ele, como que eu trabalharia na questão desses dados? hoje eu tenho que usar a réplica de escrita para escrever e ler porque o dado ele leva às vezes meio segundo ou milésimo de segundo para ser replicado como que fica essa questão de replicação dos dados ali na questão do banco, né? Você precisa já, logo em seguida, não tem como ter um atraso, você tem que já pegar o dado consistente. Sim, como que é a questão do Laravel, né? Uma questão do Laravel. Quando eu faço a autenticação, ele precisa gravar o JWT no banco, né, e depois ler, né. Tipo, gerar o token do Laravel. Então, ele tem que gravar e ler. Se eu botar uma réplica de leitura, o dado não foi replicado a tempo dele ser consumido, né. Sim, é, você grava o token no banco, é exatamente por qual motivo? O Laravel, ele já, tipo, ele tem a questão dos out, né? Então, ele próprio, ele grava a autenticação no banco, né? A sessão do usuário, né? Então, toda vez que o usuário ele se loga, ele cria aquela sessão no banco, né? Mas você precisa gravar exatamente, porque assim, se você estiver trabalhando de forma stateless, você não precisaria para poder invalidar o usuário em algum momento se você quer invalidar o token, criar ali uma block list desse motivo, que você quer gravar o que está gravando, o JWT não, é um cenário que eu tenho hoje, então o usuário quando eu uso a biblioteca do Larva de autenticação, ela precisa gravar no banco, né? E depois consumir do banco se o usuário existe no banco, né? Então, ele usa o banco de dados para poder gerenciar a sessão do usuário. Eu tenho vários cenários onde eu tenho que gravar o dado e ler, né? Uma outra situação que eu tenho também na aplicação, que é eu preciso gravar o saldo do usuário, ele se saldo. Então, se eu vou bater num banco e depois ler do outro, eu tenho inconsistência de dados, né? Então, a própria aplicação do Aurora RDS, né? Mas como que funciona, por exemplo, essa questão? Eu queria entender um pouco melhor como que está sendo você está gravando esse JWT, mas de onde você está tendo que recuperar ele exatamente agora do banco? do próprio RDS, do próprio banco de escrita hoje eu gravo ele no banco de escrita e tenho que ler dele, porque o dado não é replicado a tempo de eu consumir da réplica de leitura você está falando assim, que o usuário acabou de autenticar, gravou no banco, o token foi retornado lá pra aplicação dele, a aplicação logo em seguida já usou o token ali no header pra poder consultar alguma coisa. Na verdade, ele bate no banco de novo pra poder recuperar. Ele grava e depois ele... Ah, ele bate no... Você tá gravando e você bate no banco para poder recuperar? Você acabou de autenticar? Sim, isso mesmo. Isso é uma própria questão da biblioteca, né? Não faz sentido para o JWT, né? Ele já tem as informações necessárias justamente para não bater no banco. É que o passaporte... É porque, no caso, como eu me lembro desse passaporte, a princípio, você não precisa de nenhum storage para poder fazer esse armazenamento. O storage só é necessário se você quiser fazer essa block list. Ou seja, eu acabei de deslogar o usuário. Então, esse token vai lá para a block list, porque se ele for usado logo em seguida, ela vai consultar lá e ver, opa esse token já tá aqui você não vai poder estar autenticado pra poder acessar agora, não é pré-requisito, isso assim, eu lembro que eu usava esse passaporte já faz um bom tempo na verdade o passaporte é faz um bom tempo, na verdade o passaporte é do próprio Laravel porque tinha uma outra Lib que era a JWT que era mais utilizada antes de existir o passaporte ela não tinha, agora o passaporte eu não lembro exatamente se ele faz essa gravação, agora nesse caso eu acredito que não faça muito sentido recuperar do banco logo em seguida ali. Se você ainda está recuperando, antes de retornar ele para o usuário, esse token? Sim, o que acontece? Quando eu ativo a réplica de leitura do banco, do RDS, ele logo nunca consegue pegar a seção do usuário logado. Porque o dado não foi aplicado a tempo de eu consumir da réplica de leitura, né? Entendi, mas na hora que você está fazendo assim, você acabou de autenticar, você devolve só o token para ele ou você acaba gerando um cookie de autenticação também? Eu devolvo o token, o beer token, mas ele precisa consultar a base ele gera depois ele bate no banco pra poder consultar esse registro aí o que acontece, eu fico no loop infinito sim, sim nesse caso a solução é você não fazer a consulta exatamente não só por conta da questão da replicação, mas se ele acabou de gerar o token o token JWT ele não é um token opaco, ele é um token autocontido com todas as informações você tem ali o header e o payload você já guarda esse token num serviço pra poder já usar ali quando necessário não tem necessidade de você deixa ele gravar no banco de dados, mas você está com ele em memória. E você só retorna ele. Não precisa de você esperar a consulta novamente para que... Eu não lembro exatamente se a biblioteca trabalha fazendo a recuperação, mas se ela faz a recuperação não seria necessário exatamente ela chamar de novo o banco de dados, é necessário, acaba onerando de qualquer forma, mas você não tem essa réplica aí. Sim. Dá uma olhada se você consegue pegar, guardar, provavelmente você consegue guardar ela e já reusar sem ter que ficar fazendo essa recuperação novamente. Mas o ponto que eu tenho é sobre a replicação dos dados no RDS, né? Como trabalhar com essa replicação, né? Se eu preciso gravar um dado e depois consumir esse dado, né? Real-time, né? É, então, nesse caso, nesse caso, seria mais aconselhável Você ter Um storage Que pra seção de usuário Pode ter o banco de dados Mas se você tivesse algum outro Key value Aí seria até melhor Mais eficiente Pra poder fazer a consulta Você poderia usar qualquer key valley da vida, você pode usar um Redis ou qualquer coisa que a cloud, porque todas as clouds fornecem um key valley qualquer, já seria mais interessante, porque, ou seja, a consulta dele, a latência vai ser bem menor e você não tem essas preocupações com fazer essas aplicações e a consulta fica muito mais fácil. Porque se você não tem a preocupação de fazer um join com um JWT ou com alguma outra coisa, você pode guardar aí. Provavelmente o Passport, deixa eu ver se o Passport tem alguma coisa com com outros bancos Ele usa o ele usa a tabela Alt para, Alt Acesso para poder gerenciar os tokens os tokens gerados, né O Walter falou um exemplo de esse token para poder gerenciar os tokens do token gerado. Você até falou um exemplo de não ser só a autenticação o problema, ser também o saldo, uma consulta de saldo após ter uma gravação. Só para abstrair um pouco, de que não é exatamente o problema, não é a autenticação em si, mas o problema é a consulta após uma escrita no mesmo tempo ou muito rápido antes que esteja replicado. É porque nesse caso o que acontece, no caso do saldo, você trabalha com uma consistência eventual. Você pode olhar muitas vezes que você faz a transação você olha o saldo ali, ele pode ainda estar inconsistente aí depois que você faz um novo refresh ou alguma coisa assim, é porque demora alguns segundos, mas muitas dessas transações, elas não são síncronas você tem que esperar de fato não Luiz, tipo assim tem algum tipo de serviço crítico em que tem que exist de fato não Luiz, tipo assim tem algum tipo de serviço crítico em que tem que existir uma consistência dessas informações estou tentando abstrair para pegar exatamente o exemplo que ele deu é porque é o teorema de CAP teorema CAP mas assim, supondo que eu tenho uma aplicação, né? Eu gravo um dado no banco e eu tenho que conferir aquele dado, se ele foi gravado correto, né? Então hoje eu tenho uma réplica de escrita e quatro réplicas de leitura. Quando eu bato, eu tenho que forçar que as minhas aplicações comecem a bater na réplica de escrita só para eu poder ter o dado na base, né? É, funciona assim, ó. Imagina o cenário do Henrique ali, que ele tem as réplicas. Se eu quero manter consistência e eu tenho particionamento, né, porque eu tenho essas réplicas, então eu me afasto de disponibilidade. Muitas vezes a gente fala assim, ah, não tem. Você se afasta, porque se você tem que manter consistência com particionamento, como que você vai manter disponibilidade? Você não vai conseguir manter disponibilidade. Você tem que, ah, eu tenho que ter o saldo ali atualizado e tal. Ninguém pode pegar o saldo com o valor desatualizado. Então, você trabalha com o verde e o vermelho. Certo? Agora, se você tem réplicas e você quer manter disponibilidade... Ah, não. Bateu aqui, eu quero que o saldo esteja disponível. Então, você se afasta do verdinho. Você tem o azul e tem o vermelho. E aí essa consistência vai acontecer no momento posterior, que a gente chama de consistência eventual, que aí vai acontecer daqui a alguns segundos. Entende? Então, no teorema de Kep, nunca eu consigo ter os três ao mesmo tempo. Nunca, tá? Nunca. Nunca. Se eu quero manter alguma coisa em contato... Oi? Para a implementação, resolver, assim, escolher um desses cenários e resolver através de uma implementação, né? É assim, ou escolher a disponibilidade ou escolher a consistência. Na minha implementação. Ou escolha de disponibilidade ou escolha de consistência. Na minha implementação, eu tenho que pensar numa regra, uma regra de negócio que encaixa nesses cenários. Não daria para... Já que não posso ter os três, então vou ter que mudar a estratégia do jogo, mais ou menos isso. Eu vou dar um exemplo aqui de uma ferramenta que talvez alguém tenha usado. Você conhece o HubSpot? A gente usa o HubSpot como ferramenta para poder gerir a questão das leads e o marketing. O HubSpot é uma das maiores ferramentas do mundo. Quando você cria... O que é exatamente que a gente cria no HubSpot? A gente cria um dado no HubSpot e a gente não consegue consultar ele depois, na hora. Você tem que esperar alguns segundos. Então, por algum motivo, na hora que você faz essa transação lá via API, ele faz alguma coisa lá que demora... Pode ser indexação, pode ser qualquer outra coisa, mas é interessante isso. Você consulta logo depois, você tem já um endpoint pra poder consultar o dado e ele dá 404. Então, é uma decisão de negócio. Nesse caso aí, Henrique, seria interessante você colocar essa informação de forma segregada porque se você precisa ela exatamente ali na hora e vamos pensar assim ela não é uma informação crítica no sentido que se você não tiver o token no banco, eu não lembro eu não lembro mais tem que analisar porque aqui no fórum do LaraCaches está falando que usa o padrão em banco de dados a parte do token não é o problema nós temos a parte de pagamento hoje nosso pagamento é real-time então a gente não processa o pagamento na hora a gente tem parte da aplicação que ele tem que criar o pagamento, hora. Então a gente tem parte da aplicação que ele tem que criar o pagamento, processar e consultar ele. Hoje a gente, muitas vezes a gente força a réplica descrita para poder também responder a leitura porque o dado não foi aplicado. Isso numa escala, quando a gente escala muito, a gente conseguiu conter a escala com Dynamo na frente. Então toda aplicação é servida via Dynamo toda parte de dados somente o pagamento em si ele bate na base relacional, só que quando a gente escala, a gente tem lançamentos de muito alto a gente acaba reforçando muito essa base e a gente não consegue fazer o pagamento ser assíncrono porque a gente não consegue fazer o pagamento ser assim, porque a gente paga e se ele não pagar, ele usa outro método de pagamento, né? Sim, sim, sim. Aí a decisão, você entende, né? Que você tem particionamento. Aí você vai escolher consistência ou disponibilidade. Porque se você quer manter consistência, você vai quebrar a disponibilidade. Ah, não, não pode estar disponível esse saldo, não pode ver o saldo, então você vai manter indisponível por um tempo. Agora, eu quero que, posso ter o saldo consultado depois, posso consultar um saldo desatual agora, a minha consistência vai vir eventualmente é, hoje a gente tem a consistência vocês estão priorizando isso aqui estão priorizando vermelho e verde é isso, hoje pra nós é o principal carggado que a gente tem a gente consegue escalar os containers até onde dá, mas quando a gente precisa que o banco escale, o banco ele é o que sofre Bom, mas pra esse caso específico, como é um caso crítico e apartado, talvez você poderia usar um cache na frente da escrita você escreve no cache e depois você escreve no banco. Aí você pode colocar até um período do cache de TTL baixo, mas ele vai ser usado como primeira fonte da verdade na leitura. Aí você bate nele primeiro e depois bateria na réplica. Sim. Você pode usar um cache, inclusive, até de HTTP, se, não sei o contexto inclusive falando aqui muita gente considera que o cache tem que ficar em algum lugar, você pode usar o próprio HTTP caching com o Nginx na frente com os headers ali do e-tag mais as questões do browser ali, você consegue manter um cache com baixo custo. Tá. Eu acho que hoje a saída é usar uma base, uma outra base, poder gravar e depois desaguar no banco relacional. É, você tem que usar alguma alternativa, porque assim, não dá pra você poder esperar no caso do JWT consultar ali na hora e você tem essa estrutura e esperar a replicação, não rola porque se você esperar você está atravancando a resposta HTTP e diminuindo recursos pra outras chamadas que estão chegando sim é, mas o grande problema que eu tenho e diminuindo recursos para outros chamados que estão chegando. Sim. Mas o grande problema que eu tenho hoje é a replicação do RDS. Para várias situações eu tenho que forçar a réplica de escrita. Ler da escrita porque o dado não foi aplicado a tempo. Eu acho que a gente não vai se livrar muito disso Não sempre vai ter um tempo de atualizar as réplicas Acho que nesse ponto Não tem nem o que fazer Mas acho que essa ideia do cache Na frente é legal Não sei a confiabilidade de um cache Se ele quebrar antes de subir Para o banco Mas eu achei interessante depois Henrique se você quiser bater um papo senão a gente termina aqui, pode conversar mais, se quiser me marcar no Instagram e a gente vê outras alternativas, mas sim, o primeiro entendimento é esse, a gente tem que saber que o cenário nunca vai ser perfeito você tem os três pontos aqui, não é que você sempre vai ter que escolher dois, mas você sempre vai priorizar mais dois e um deles não vai ser prioritário acho que fica mais claro assim então essa questão do cash não vai ser prioritário. Acho que fica mais claro assim. Então, essa questão do cache, ela é muito importante, aproveitando o assunto. Não é somente Redis que existe, existe main cache também, que é uma solução muito mais leve, né? Porque o Redis, ele faz muito mais coisas do que só cache. Banco de dados pode usar cache, até disco pode ser cache, o HTTP pode ser um cache também. Então, é necessário você saber quanto de cache você precisa, porque cache não é infinito. Qual tipo de cache você vai utilizar. Não despreze o cache em browser e no próprio servidor web, que ele é muito mais barato de ser implementado. Inclusive, o Ray Fielden, criador do REST, vou colocar aqui, o Ray Fielding, criador do REST, ele fica muito triste quando a gente não usa stateless. Tem até um meme da Ray Fielding. Aqui, não sei se vocês já viram esse meme aqui. Aí você fala para o Ray Fielding que você está criando uma API RESTful. Aí você fala, usando o JSON, o sorriso já se perdeu e depois, aqui estão meus API docs, justamente porque quando você está criando o REST, você deveria trabalhar com Hypermedia e ela já deveria ser a primeira documentação da sua API. Mas um princípio da dissertação do Roy é justamente a sua API ser stateless, porque quando a gente é stateless, o caso do Henrique que ele está passando ali, ele precisa ser stateful, né? Quando eu sou stateless, eu consigo ter uma arquitetura, por exemplo, na frente da minha API de ProxCache ou de Nginx ainda na frente, com API Gateway, que eu não tenho que guardar estado, todo mundo se comunica com todo mundo sem o compromisso que ele tenha que recuperar a informação em algum lugar. Então, quando você é stateless, tem muito benefício de usar o próprio HTTP caching. É muito fantástico o que dá para obter. Mas também eu preciso saber, além do quanto eu vou usar de cache, tudo isso, qual a estratégia de invalidação. Vai ser invalidação baseada em evento, quando acontecer uma mudança em algum dado, eu vou revalidar o meu cache, baseado em tempo, no uso, que está mais recente, na frequência de uso, enfim, existem várias estratégias. Então, vamos pensar um pouco mais com calma também em monolitos, porque isso aqui acaba piorando mais o cenário ainda, e um cenário que acabou quase inviabilizando a nossa aplicação foi o próprio Redis, porque o Doctrine ele guarda o mapeamento objeto relacional em arquivo, não dava pra guardar em arquivo, porque a gente tinha réplicas dessa aplicação quando nós mudamos para a Docker, e aí nós utilizamos o Redis para poder concentrar. Então, acontece que o banco de dados vai mudando. Então, ele vai gerando versões desse mapeamento, versão 1, 2, 3, e você tem que fazer com que cada réplica esteja ciente dessa nova versão, mas o problema é que o Doctrine ficava, para cada réplica gerada, ele ficava criando novas versões, e o mapeamento nosso é muito grande. Então, enquanto as réplicas antigas estavam sendo destruídas, as novas se eu tivesse 4 novas ele gerava 4 novas versões e é difícil você como você tem novas réplicas de ficar centralizando para ele criar uma só por conta da deficiência do próprio URM só para poder simbolizar. Então chegou um ponto que o nosso Redis estava com 8 GB de memória, 20 GB, chegava um ponto que ele não aguentava, se o mapeamento não funciona, a aplicação quebrava. A gente teve muitos momentos de indisponibilidade com isso, e pensando exatamente que era banco ou era outra coisa, era justamente esse uso do Redis. E pensando exatamente que era banco ou era outra coisa, mas era justamente esse uso do Redis. Mas na verdade, a gente acabou tirando o Redis fora e nós criamos um mapeamento local, em disco mesmo. A gente conseguiu fazer essa alternativa, tornando muito mais leve e deixando o Redis somente para cache de algumas carries. E até lembrei de um ponto, antes da live, eu falei, eu vou falar isso porque isso é muito importante. Vamos supor que você tem um endpoint, criar aqui um novo arquivo. Luiz, mas aí ele se manteve stateless? Se manteve stateless. O que acontece? Ele se manteve stateless? Se manteve stateless. O que acontece? Deixa eu voltar aqui a minha apresentação. Toda vez que vai criar as réplicas, a gente gera um serviço antes, ele gera esse mapeamento e joga para as outras. As outras elas pegam esse mapeamento já em file. E aí fica muito melhor porque a latência, tem uma certa latência para poder ficar acessando o Redis. Porque o PHP não é igual o Node ou o Go, que ele fica rodando o processo o tempo inteiro. Ele é provocado cada vez que chega uma chamada. Então, ele tem que se carregar, ele carrega o framework inteiro toda vez que recebe uma chamada. Ele não carrega tudo para a memória. Então, nesse caso do disco aqui, a leitura local do mapeamento ficou muito melhor. Mas aí a gente criou aqui algo como está usando com Kubernetes ali, por exemplo. Se eu tenho que fazer uma mudança na minha entidade e fazer a remoção de um campo, primeiro, eu tenho que tirar o uso desse campo em toda a minha aplicação, tirou tudo, você vai ter ali as atualizações aí vai ter uma nova atualização somente para poder ter essa remoção entendeu? porque se eu pegar um campo de uma entidade e remover ele essas instâncias antigas que estão rodando vão precisar utilizar esse campo as novas não aí vai dar problema com o RM vão precisar utilizar esse campo. As novas, não. Aí vai dar problema com o RM. Por quê? Eu matei lá no banco de dados as antigas e ainda estão processando alguma coisa. O mapeamento vai, opa, peraí, não tem o banco lá no banco de dados, não consigo recuperar esse dado, bum, dá erro, aí as antigas param de funcionar, as novas não sobem. Aí tem que fazer rollback de migração, algo assim. Entende? Então, isso é o que normalmente é feito quando você trabalha com as réplicas. Quando tem uma alteração crítica em banco ali, que as réplicas antigas e novas divergem, você, nesse caso, gera somente ali, que as réplicas antigas e novas divergem você nesse caso, gera somente uma nova atualização pra poder mexer naquele campo ali e ele não tá sendo mais utilizado e pronto entendeu? não sei se ficou claro isso aí só pra passar a ideia tipo assim, muitas vezes usar o cache no Red vezes, usar o cache no Redis ou usar o cache por si só não é a resposta trivial. Muitas vezes, outras alternativas podem ser melhores. Mas, o que acontece também com REST, tá? REST, ele é um... é uma arquitetura que muitas vezes a gente usa errado, vou dar um exemplo quero usar HTTP Cache certo? Cache, na verdade aí eu tenho um endpoint, estou dando um exemplo de capítulos dos cursos esse endpoint aqui ele retorna o id, o nome do capítulo e alguma outra coisa. Mas aqui ele coloca também o progresso do usuário. O que que tá errado aqui? esse endpoint ele era pra ser mais genérico e ele está orientado ao usuário eu não consigo fazer o cacheamento dele em nível de HTTP porque ele guarda aqui um usuário eu não posso fazer o cache dele, porque senão um usuário ia pegar o progresso do outro. Então, muitas vezes, por conveniência, a gente acaba criando endpoints que retornam muitas informações, você adiciona informações do usuário e aí impede de você usar o cache em HTTP. Porque se eu tivesse o endpoint separado para poder capítulos, por exemplo, progress user, e outro somente para capítulos, todo mundo que estiver acessando barra capítulos daquele curso vai ser cacheado. Aqui pode. Então entende que o design do REST ele afeta também como você faz o cache, porque aí você acaba encaminhando sempre para o cache de uma ferramenta externa. Quando o próprio HTTP é uma solução muito barata e eficiente. Eu posso colocar esse cache aqui no Nginx. Aí se eu tiver milhares de chamadas, bate no Nginx em vez de bater na minha aplicação O Nginx roda aí com 10 MB de RAM Você já consegue rodar o Nginx Atendendo milhares de solicitações, né? Agora, uma aplicação como a nossa roda muito mais Escalar ela gera muito mais custo. O Nginx não. Se eu escalar aqui um outro Nginx com mais 10 MB, consigo atender a mais milhares de solicitações. E aí, se as requisições batem nele, evitando de bater na minha aplicação, estou evitando até mesmo de usar qualquer cache externo. Então, dê uma olhada no cache HTTP e o design do Sphere REST afeta totalmente muitas vezes esse design que você coloca muita coisa num lugar só eu sei de onde vem, sabe de onde que é lá dos front-enders não, mas é porque se eu fizer várias chamadas, vai complicar aqui, né, vou ter que fazer tratamento de erro vai complicar minha vida coloca tudo só no endpoint é mentira que eu tô falando e não é mentira né tô vendo aqui ó onde vocês na cama não é mentira o resto surgiu até um becky and for front-end por causa disso É, exatamente Quando o Roy Fielding Ele não é só o criador do REST Ele foi o cara que Participou da migração Do protocolo HTTP Versão 0.1 para 1.1 Na verdade, o contrário Ele participou da migração Do PHP versão 1.0 Para 1.1 para 1.1 na verdade, contrário ele participou da migração do PHP versão 1.0 para 1.1 ele foi o propositor do verbo patch, ele é uma das principais referências na web que nós temos lá, junto com o Tim Bersley e outras pessoas, a ideia do REST é que a gente tenha muitos endpoints e seja stateless. Justamente porque quando eu estou trabalhando aqui também com o Progresso, eu não estou sendo stateless. A ideia é que eu posso fazer esse cache aqui, esse cache pode estar compartilhado ali para o API Gate, para o Nginx, para o Proxy Cache, qualquer... Eu posso ter uma malha de estrutura de outras aplicações na frente da minha aplicação. Então, não tenha medo de fazer várias chamadas. Ah, mas se eu fizer várias chamadas, vai aumentar a latência? Poxa, se você está fazendo cache, não aumenta a latência. Porque você pode fazer cache no browser, no seu servidor web, num proxy cache, e ainda trabalhar com o e-tag na sua aplicação. Dê uma olhada nisso. Tudo isso aqui é HTTP cache. Tudo isso aqui é muito barato de manter. Muito mais barato que um Redis da vida. E a ideia do REST justamente é essa. Quanto mais você é stateless, mais você tem benefícios. Mais a sua infraestrutura pode colocar um monte de coisas na frente A ideia é essa, que eu não tenha limitações Eu posso trocar o Nginx por Apache Eu posso colocar o Envoy na frente E mais um monte de outros servidores webs Então isso aqui ajuda demais Quando você entende melhor qual tipo de cache a ser utilizado Você melhora a performance da sua aplicação. Aí aqui eu coloquei alguns dados, pois o Leonardo acaba disponibilizando as gravações que vocês podem ver, tudo que eu estou falando aqui de file system e tudo mais com o Redis. HTTP também é outro problema para uma aplicação, você pode ter, como eu estava falando, Rust, Golang na sua aplicação, mas HTTP é o problema. Vai gerar latência, vai atravancar tudo. Então, nós temos que ter uma certeza que quando você faz chamadas HTTP de dentro do seu monolito, da sua aplicação, de forma geral, não é se vai falhar a chamada. Ela vai falhar em algum momento. Mas o problema não é nem esse. É quando a sua chamada é lenta. Porque quando ela falha, você recebe uma resposta pelo menos rápida, né? Ah, recebi ali um erro 500 lá do meu gate de pagamento. Recebi um erro 400 do meu serviço de e-mail. Agora, quando você tem uma rede lenta ela mata a sua aplicação porque ela fica esperando aquela chamada acontecer durante um certo tempo e aí impacta em todas as chamadas que você está recebendo ainda mais se você tem muitas aplicações comunicando você recebeu uma chamada que ela passou para outra e ela precisa esperar ali três aplicações comunicarem para poder dar uma resposta então, retentativas, timeout também é muito importante configurar talvez colocar um timeout pequeno, médio aí é interessante, você sabe que se demorar mais de dois segundos não precisa nem ficar esperando isso já ajuda você devolver uma resposta é um retry também você pode fazer um retry com backoff então eu posso tentar fazer três retentativas de alguns milissegundos, isso já ajuda também, porque você não tem que fazer a chamada, fazer todo o processo novamente. Limite o número de retries, que sejam dois, três, já ajuda bastante. Ou até retries condicionais. Você sabe que determinado erro, você não tem como recuperar. Não faça retentativas. Já retorne um erro para o usuário, já faça alguma coisa ali que registre esse erro. Agora, esses erros específicos, a gente sabe que tem uma chance grande de retentativas, então retente, dado os determinados tipos de erros. Mas tem um padrão que é muito utilizado em microserviços, mas pode ser utilizado com monolito, que é o Secret Breaker. Você sabe que sua rede está lenta? Não só, às vezes, é a aplicação de terceiros que você está se comunicando ou a aplicação interna da sua empresa. Mas a rede, por si só, está lenta. Não é culpa das aplicações. Então, você tem ali aquele circuito, provavelmente tem uma chave aí na sua casa que se acontecer uma descarga, ele vai desarmar e vai cortar a energia para não queimar os seus aparelhos. Normalmente as casas hoje em dia tem isso. Então o circuito abre, já vou receber os erros na hora, e aí eu evito que eu tenha uma rede lenta. E é sempre isso, rede lenta e é sempre isso rede lenta é pior que falha você pode implementar isso na mão mas APIs gateways ajuda bastante nisso, elas já implementam isso por padrão elas vão ficando fazendo as chamadinhas pequenas lá pra aplicação alvo e aí elas veem se tá lento, se tá dando tudo certo aí ela volta a deixar as chamadas passarem de novo o circuito fica fechado quando está dando tudo certo, aí ela volta a deixar as chamadas passarem de novo então o circuito fica fechado quando é deu problema e ele abre para que as chamadas continuem acontecendo Cron Job Event Driven também é importante para aplicação monolítica porque você vai precisar fazer processos em background então não tente fazer tudo de forma síncrona política, porque você vai precisar fazer processos em background, então não tente fazer tudo de forma síncrona. Você pode ficar rodando processos aí pra poder rodar, a gente tem aqui as nossas notas fiscais, é rodado com CronJob, a gente não usa EventDriven, os processos são rodados de tempos em tempos, levanta lá a aplicação numa perspectiva diferente, é o monolito, mas ela vai lá e faz a declaração das notas. Processamento de leads, pagamentos e contratos também, a gente de dar a resposta ali na hora, mas cuidado também para não fazer um cronjob imenso, fazendo com que fique inviável a execução dele, ele pode recuperar muitas informações do banco para poder fazer essas chamadas, talvez você possa fazer de forma paginada, então tem várias alternativas também para poder torná-lo mais leve, mas em determinados cenários trabalhe com event driven trabalhe de forma assíncrona produza um evento, publique no message broker qualquer, não importa e a outra aplicação vai consumir no tempo dela aí você não vai precisar esperar uma resposta na hora. Você consegue escalar muito melhor a sua aplicação monolítica, a outra consome lá quando ela tiver vontade, se ela estiver fora do ar, ela volta e consome. Você pode publicar isso aqui para outras aplicações também, permitindo que você processe coisas depois. Lembre, real-time não tem que acontecer necessariamente na hora, eu gosto muito de parafrasear o Valgvernon, ele fala que o real time muitas vezes pode ser 5 minutos uma hora dependendo do real time para muitos setores das empresas, não é exatamente ali milésimos de segundo então quando eu trabalho com event driven também eu permito um escalonamento muito maior, porque eu já me livro aqui de fazer todo aquele processamento de negócio, ele vai ser processado, daí um tempo. A gente processa com o Event Driven estatísticas do aluno, toda vez que vocês fazem uma visualização lá de vídeos e outras coisas, cai no nosso ReptMQ, e aí a nossa aplicação de estatísticas do aluno consome. Também vai para IA. Nós temos uma aplicação de IA que vai consolidando os eventos que vocês vão fazendo e vão gerando outras informações e até mesmo ajudando no fórum também que a gente acaba tendo IA. Melhorias de arquitetura e design. Importante também, aqui vai mais para o ponto mais técnico. O SRP lá do Solid. Trabalhar com Single Responsibility Principle, né? Lei de Conway. O princípio da responsabilidade única, lá no livro da Clean Architecture, é falado que ele se espelha na lei de Conway, que ela fala que a empresa vai produzir o software com base na sua estrutura organizacional. Se você tem front-end, mobile e back-end, você vai acabar tendo esses sistemas. Mas o que o Uncle Bob está falando em relação ao desenvolvimento é que quando você tem determinadas partes do seu software, pode ser até partes menores, que elas atendem a múltiplos setores ou múltiplos usuários diferentes, vão chegar necessidades diferentes de mudanças que vão entrar em conflito, fazendo com que aquele módulo ou aquele trecho vá mudando, atendendo esses conflitos, e aí você vai perdendo o controle sobre ele. Então criar classes ou serviços diferentes para atender a tipos de usuários diferentes pode ajudar bastante, porque quando chegar uma necessidade de mudança lá num serviço que atende a um setor da sua empresa, não vai conflitar com outro serviço que está atendendo a outro setor. Então, esse princípio aqui não é para a sua classe ter um motivo para mudança, não é isso. É para você poder olhar quais os tipos de usuários são os clientes dessa classe. de olhar quais os tipos de usuários são os clientes dessa classe. Se você tem tipos de usuários diferentes, você acaba tendo esses conflitos. Então, isso ajuda a agrupar as coisas melhores. Esse princípio aqui ajuda muito a separar monolito muito bem. A gente faz isso bem. A gente tem uma área ali do aluno que é totalmente separada da área administrativa então quando surgem mudanças alguma coisa, o feedback de vocês, alguma coisa que a gente está mudando não conflita com coisas que nós temos na área administrativa porque veja só, vocês precisam consultar os cursos os nossos tutores e a gente precisa ver os cursos também, mas numa outra perspectiva. Nós separamos essas responsabilidades, para justamente não dar esse conflito. Então, muitas vezes pode ser criar serviços separados, ou criar módulos separados para poder atender a essas necessidades. Usar Design Partners para problemas comuns também é muito importante. Container de serviços é essencial para uma aplicação monolítica, porque você não fica rateando para poder criar as coisas, você acaba trabalhando com injeção de dependência e mais também com inversão de dependência. O container de serviços acaba sendo delegado a responsabilidade de entregar o serviço ali para cada parte do software. O que eu estou falando, container não é doc, né? É o conceito de container mesmo, é que o Symfony tem, o Laravel tem, o Spring tem, o Django tem, todas essas aplicações têm, muitas vezes elas não são utilizadas ou são mal utilizadas. Mas também outros design patterns como adapter, factor, strategy, veja se às vezes design patterns não resolvem problemas comuns que você já tem. Porque muitas vezes o design pattern é usado errado em aplicações que você está criando, você não tem esses problemas e vem aquela síndrome de paternite que você vai usando o design pattern só por usar. Não, em monolitos você já tem uma série de problemas. Casa muito bem com o design patterns. Com certeza você vai pegar os criacionais, estruturais e outros tipos que vão ajudar bastante a organizar esse código e permitir que ele seja refatorável ao longo do tempo. A ideia justamente é permitir que esse monolito tenha uma sobrevida. Parte de arquitetura de software. Trabalhar com arquitetura em camadas, pelo menos. Ter um MVC, uma camada de negócio separada do seu controller. Eu vejo muito, pessoal. Eu já dei muita consultoria que você tem regra de negócio dentro de controllers. Vocês não tem noção das coisas que eu já vi, tá? Aí, na hora que eu entro pra fazer reunião e tal, a gente tá pensando em separar microserviços ou usar o framework da versão mais nova. O problema não é esse que você tem. Você vai usar o framework da versão mais nova e você vai colocar a regra de negócio nos lugares errados. E o problema vai ser o framework. E assim, muitos problemas que a gente tem nas nossas aplicações são questões simples. Então, arquitetura em camadas. Cada camada tem a sua responsabilidade. Camada de negócio não se mistura com camada de apresentação, não se mistura com controller. Ter pelo menos o application service é importante. Aí, dependendo da situação, criar uma separação de camada com a Clean Architecture pode ser muito legal, não precisa de usar todas as camadas da Clean Architecture, mas a separação de Use Cases pode fazer com que não gere conflito entre as pessoas que vão fazer as manutenções, porque o Use Case pega só um caso de uso, né, você não tem o Application Service, você concentra muitos casos de uso num lugar só. O Use Case da Clean Architecture, você só pega um caso de uso específico. Aí, se tiver que trabalhar com o domain model também, vai ajudar bastante, porque vai desacoplar um pouco mais da parte técnica com esse monolito. Ele vai ficar muitos anos, ele vai permitir que você troque os ORMs, troque outras coisas. Então, veja também, muitas vezes não precisa trabalhar com Domain Design. Domain Design e Domain Model estão relacionados. Por quê? Domain Design utiliza Domain Model. Mas você pode trabalhar com Domain Model sem trabalhar com Domain Design. É basicamente você pegar essas regras de negócio que acabam ficando espalhadas ali na sua camada de serviço e jogar ela de forma mais granular para dentro das suas entidades. Isso já vai ajudar bastante, porque você vai ter um reuso melhor disso e uma concentração aonde essas regras deveriam estar, dada a complexidade que você tem. Trabalhar com arquitetura multi-tenancy. Eu vejo também um erro muito crasso em empresas arquitetura multi-tenancy não precisa necessariamente ter múltiplos bancos de dados, existem vários modelos é porque se pensa que um banco de dados só não vai atender a solicitação pessoal, bancos de dados são feitos para poder atender uma carga muito grande de consulta escrita se você está gargalando o banco é porque você está fazendo alguma coisa errada. A maioria das aplicações multitenas do mundo são um banco compartilhado. Eu não estou falando de aplicações pequenas, só não, aplicações grandes. Múltiplos bancos de dados servem a cenários distintos, tipo, sei lá estou fazendo uma aplicação multitênis para prefeituras aí por questão legislativa lá eu preciso ter múltiplos bancos de dados ou eu tenho alguma questão específica que eu preciso fazer essa separação porque um cliente meu tem uma demanda ou 20% dos meus clientes, tem uma demanda muito absurda em detrimento dos 80%, aquela lei de Pareto, 80-20. Então, eu vou criar bancos de dados diferentes, porque para esses 20% aqui eu vou dar uma carga muito maior em detrimento desses 80%. Então, tem que ter uma motivação grande, mas a maioria dos casos é multi-tenancy com um banco de dados só. A gente não acaba utilizando multi-tenancy porque a gente não tem estrutura para isso, mas olha só um caso que a gente quer utilizar. Nós temos hoje duas escolas ativas. Tem a Full Cycle e a DevOps Pro, que é nossa também. O que a gente faz na nossa infraestrutura? A gente duplica. A gente duplica a infraestrutura inteira. É, mas, poxa, por que vocês não estão implementando multitênis? Exatamente, porque a aplicação não foi pensada assim no início. Se a gente fosse fazer uma arquitetura multi-tenancy ia gerar tantos problemas ia levar tanto tempo a questão é que quando a gente adquiriu a DevOps Pro a gente já queria lançar na hora mas a gente sabe que a gente precisa mudar pra multi-tenancy porque isso vai reduzir custos e permitir que não se gere duplicação de bugs ou problemas em um e outro, não. Porque se eu estou duplicando a infraestrutura, por que que às vezes a DevOps Pro está com um problema e acontece muito? Justamente porque eu tenho duas infraestruturas diferentes, mas é a mesma aplicação, mas são dois bancos de dados separados, enfim então, muitas vezes a gente tem que saber também onde que a gente está e pra onde que a gente vai. Strangler Pattern eu já falei lá atrás muitas coisas que a gente queria acrescentar e viu que não era legal por causa de tecnologia ou de negócio nós adicionamos uma nova aplicação, criamos uma nova aplicação ou tiramos alguma coisa do monolito nosso, como o fórum, por exemplo. O fórum a gente tem totalmente separado. Então, isso pode ser uma alternativa interessante para fazer o seu monolito também não ter coisas que não fazem sentido para o negócio. Modularização. Separar aplicação em módulos é muito importante. Aqui vai o uso também de Clean Architecture, vai ajudar muito nesse caso. Usar Design Patras também, como o Design Patra é façade. Você pode organizar os seus use cases e criar uma façade para a façade somente expor as funcionalidades para os outros módulos. Esses módulos só vão se comunicar através dessa façade. Então ela vai esconder todos os detalhes de implementação para trás. Isso ajuda bastante você ter mais independência. A gente fala bastante sobre um monolito modular. Tem muitas empresas que decidem ir para esse caminho. Você acaba tendo mais independência entre os módulos e criar uma melhor separação entre os times, porque quando você tem esses módulos bem divididos, mesmo que você está na mesma aplicação, você consegue ter uma melhor separação entre as necessidades dos times, até mesmo o nível de conhecimento. Eu posso pegar um time que eu estava falando lá atrás. Aqui, esse módulo, ele é crítico. Então, nós vamos colocar os desenvolvedores mais talentosos aqui. Agora, esse outro módulo não é tão crítico assim. A gente pode colocar o pessoal que está começando e tudo mais, colocar ali alguém mais experiente no time, enfim, fazer um balanceamento melhor. Front-end. Pasmem, lá atrás nós tínhamos um AngularJS com jQuery, foi assim que a aplicação foi criada, não tinha Webpack, não tinha nada dessas coisas novas, se utilizava RequiredJS, quem aí já usou? RequiredJS mais Asynchronous Module Definition. Quem aqui sabe o que é isso? AMD, JavaScript. Quem já trabalhou? JavaScript virou meio que uma baderna alguns anos atrás, porque a linguagem meio que não tinha uma definição para onde ia. Foi se criando... Não, AMD não é processador, é padrão de módulo JavaScript. Se criou lá atrás, com o mod, o AMD mod, depois veio S6, enfim. A comunidade foi criando um monte de padrões modulares ali para poder tentar organizar melhor o código. Então, nessa época aqui, não tinha Webpack, Vite, nada disso. Aí, se construía um SPA com o AngularJS e o jQuery pra poder organizar algumas coisas. Aí, esse jQueryJS pegava todos os módulos do Angular e ia carregando pra poder transformar ali no SPA. Esse SPA demorava alguns segundos para poder responder, era muito pesado ficar carregando as Libs dessa forma, as Libs eram carregadas de forma assíncrona. Por quê? Se a gente fosse carregar toda a aplicação de uma vez, ela já era pesada. Se carregasse toda de uma vez, ia demorar muito tempo, ia ser muita coisa ali no browser do usuário. Então, assim, não tinha otimização, era muito complicado trabalhar com isso aqui. A gente tinha apenas sessão e cookie. Então, assim, dentro do barra login do Symfony, carregava esse SPA, não tinha JWT nem nada. SPA, não tinha JWT nem nada então pense que pra poder fazer atualizações era um monte de arquivos separados toda hora gerava problemas, não dava pra poder ficar usando cache tem hora que tinha que saber se o módulo tal tinha sido atualizado ou não, e a gente usava uma tagzinha com uma libjar, que era uma coisa misturada com o symfony pra poder ir atualizando a SPA. Chegou um ponto, né, que não dava mais pra atualizar esse negócio, não era compatível com nada atual, não tinha package JSON nisso aqui. Você tinha que pegar todas as libs e jogar no source code. Era tudo assim, ah, eu estou pegando o Axios. Copiava lá na pasta de libs. Era tudo carregado com esse troço aqui. Então a gente decidiu jogar isso aqui fora e construir uma aplicação SPA totalmente separada. Isso aí acaba sendo um Stronger Pattern. Nós tiramos a parte do SPA lá de dentro, na verdade ela até continua lá, mas criamos uma nova aplicação. A área administrativa... Isso não faz 10 anos, né? Isso não faz 10 anos atrás, né? Pra ver como mudou. Sim, sim. Antes de 10 anos atrás, isso. A parte administrativa continua sendo feita com o Twig, que é o template engine lá do Django pra poder pegar as coisas, tornar dinâmico o HTML, tem uma lib Java pra poder fazer o join dos assets isso aqui é usado, tipo assim vamos supor que você tenha vários assets, aí você coloca uma tagzinha lá no Twig, ele pega e roda uma quando você vai fazer o deploy ele gera, junta todos esses assets era coisa que usava antiga tipo era uma é uma lib chamada é eu vou lembrar de cabeça e é isso aqui ó e o ai arroba isso aqui ó e se existe ainda? Dá para download aqui, é o site, né? Estilo do site, bem antigo. É um jarzinho, o Twig, o Symfony incorporava isso, né? Então era muito desatual, a gente estava tendo esses problemas de quebrar JavaScript lento, ficava costurando coisas toda hora e tal, então a gente decidiu fazer essa mudança aí. A gente começou mudando para React, com o Create React App, depois migramos para a Vite, porque torna muito mais fácil o deploy. A gente demorava uns dois minutos para fazer o build, agora a gente demora dez segundos com o Vite, porque o Vite utiliza um cara chamado de SBuild, que faz as transpilações do JavaScript e tudo mais com o Go. A autenticação é feita com o JWT e a aplicação, essa é uma das poucas aplicações que ficam fora do nosso ambiente. Ela fica hospedada no Cloudflare Workers, que é um serviço para você poder hospedar o seu front-end, é bem bacana. E aí ela vai se comunicando com a aplicação PHP. Containerização, isso aqui ajudou demais Tudo que a gente roda Local e online Exceto essa aplicação, obviamente Porque o Cloudflare Workers não trabalha com Docker Mas tudo roda com Docker Os nossos desenvolvedores são obrigados a usar Docker Se você não usar Docker Não, estou brincando, tem chicotado Mas todo mundo utiliza Docker local ligados a usar Docker. Se você não usar Docker, dá chicote. Não, tô brincando. Tem chicotado, mas... Todo mundo utiliza Docker local, tá? Todo mundo domina Docker. Mas hoje não tem como não usar. Hã? Hoje não tem como não usar. Sei lá. Não, mas o problema é que, talvez, pra vocês, que a gente evangeliza muito Docker, né? Vocês assistem muitos eventos nossos, mas vocês não têm ideia do quanto de profissionais que não utilizam o Docker. Eu já tive aluno perguntando assim, Luiz, eu tenho aqui um Java legado 5 com aplicação monolítica, como que eu faço para poder evitar os problemas de execução? Porque na minha máquina dá um problema eu peguei isso num evento que foi ano passado foi usar Docker, ah mas dá pra poder resolver com Docker? Sim, dá pra poder resolver com Docker, a gente tem essas questões ainda, então assim usar local ajuda demais porque o desenvolvedor já tem uma prévia de como que funcionam coisas, mesmo que seu ambiente de dev com docker não seja muito espelhado, que seria recomendado ele deve ser o mais próximo de produção tem muitas empresas que acabam evitando isso, tem muitas empresas que usam ah não, uso docker para produção, adoro lindo, desenvolvimento, tô fora pra nós foi essencial, porque na hora que eu comecei, na hora que a gente começou a usar a Docker tanto pra desenvolvimento quanto pra produção, começou a mostrar as cagadas que a gente tava fazendo nas aplicações, porque container ele tem recurso limitado em todos os sentidos, né? O container é um processo. Ele é totalmente capado pelo sistema operacional. Então, o sistema operacional limita escrita, limita leitura, limita CPU, limita memória. Quando você está fazendo o deploy em uma VPS, é tudo lindo, porque tem aquela limitação ali, mas você até pode extrapolar um pouco mais. Então, quando a gente começou a rodar isso aqui, ajudou os ambientes, minimizou esses ruídos aí que na minha máquina funcionam, e a gente já tem uma prévia de como que as coisas vão sendo executadas. Inclusive, o Docker ajudou lá atrás, que eu tinha falado, no caso dos testes, né? Porque a gente estava rodando os testes em CI, e no GitHub Action, ele não estava aguentando. Então, a gente começou a perceber que era um limitador de file description. Isso no Linux, né? Quando você tem um processo, ele tem um número de arquivos que ele pode lidar, é um número limitado. Então, por causa do symphony de como as coisas eram configuradas, ele ficava abrindo tantos arquivos a cada teste que ele quebrava. Então com o Docker a gente conseguiu fazer um teste. Nós pegamos o container, aumentamos o file description, ah, peraí, isso aqui que resolveu o problema. Mas isso aí foi fácil justamente porque com o Docker, você simula ambientes, você troca as coisas, você consegue experimentar sem ter o medo de errar, porque a qualquer momento você destrói, o container é efêmero. Agora, o ambiente da sua máquina, você tem medo o tempo inteiro para poder fazer as coisas. Porque se você fizer alguma coisa na sua máquina, o que você vai fazer? Formatar e tal, mais Docker. Você pode fazer todas as asneiras que você pensar. Então, você vai tendo progressão de ambiente, fácil para poder rodar em qualquer lugar. E aí vem essas opções de Dev Container. Eu tenho um vídeo no na full cycle de mais de 250 mil visualizações eu mostrei como funciona deve container de caba rápido uma olhada lá é porque ele joga o ambiente do por exemplo do verso code no dentro do container ali as extensões conseguem chegar dentro do. Até mesmo as ideias da JetBrains conseguem enxergar o DevContainer. O cursor é baseado no VS Code, entende o DevContainer. Dê uma olhada aqui porque é muito fantástico. Fora que às vezes você consegue desenvolver no próprio browser, né? Tem o GitHub Codespaces. Você consegue alugar uma máquina e desenvolver com o ambiente ou no browser, ou você pega o VS Code e conecta no servidor da GitHub lá. Você pode pegar uma máquina com 32 GB de memória, algo muito legal. Então, torna o ambiente muito mais fácil. Isso aqui, tipo, a gente nem... Eu nem lembro a última vez que a gente teve problema com o ambiente. Eu só lembro das vezes que toda hora alguém chegava pra mim e pro Wesley não tô conseguindo rodar esse negócio aqui. Ah não, peraí, vamos dar um banco de dados, vamos rodar isso aqui vamos fazer tal coisa e tudo mais. Eu lembro agora, a última vez, eu não lembro porque faz muito tempo. E Docker pra produção também, muitas empresas acabam não utilizando. Muito importante, porque você não fica preso a cloud nenhum, roda em qualquer lugar e você acaba tendo a possibilidade de rodar esses serviços autogerenciados, como AWS, SS, os containers da Amazon. Azure Container Service, da Azure, lá da Microsoft. Google Cloud Run. Outros também têm os seus serviços gerenciados. Você aluga somente o container. Não precisa se preocupar com o ambiente nenhum. Quando o container não está sendo utilizado, gera economia para você. Então, não precisa rodar com Kubernetes ou nada do tipo. Esses serviços aqui já conseguem ajudar bastante também. Então, Docker para produção melhora muito toda a infraestrutura, ajuda no deploy, ajuda os desenvolvedores, porque você está rodando um ambiente mais próximo, né, e você acaba sendo um incentivo a ser stateless, porque o container você sabe que uma coisa certa é que ele vai morrer, você não vai fazer o payload de arquivos no container, você não vai colocar coisas que precisam ser persistidas nele porque container, eu tenho que criar mais quatro containers agora, eles podem morrer, eu vou criar mais oito, eles morrem. Então você começa a pensar na sua aplicação dela ser stateless. Lembra que a gente estava falando que ser stateless é um cenário bom demais, nem sempre é possível. No caso lá do Henrique Brits, se eu lembrar o nome dele, não dá para ser stat ainda com banco, né? Bancos de dados, eles não conseguem ser status. As nossas aplicações tendem a ter esse incentivo, mas muitas vezes você tem status lá dentro dela, tem o payload lá dentro dos próprios arquivos, você está trabalhando de modo status, isso vai evitar você escalonar, por exemplo. Você não vai conseguir matar aquele processo ali porque ele está com aqueles arquivos, está dentro dele, daquela instância do container. Agora, se você armazena as coisas fora, tem tudo fora, aí você pode ter muito mais liberdade. Continuous integration, continuous deployment. Essa aqui é a nossa infraestrutura hoje para poder fazer os deploys, não só dessa aplicação monolítica como das outras. Dev faz um pull request no repositório chamado de Code Platform, aciona uma GitHub Action, aí nós publicamos as imagens Docker, não no Docker Hub, mas no GitHub Packages, que é um serviço de imagens da própria GitHub, porque como está local ali com a própria GitHub Action, para poder gerar as novas versões das imagens é muito mais rápido. Se eu puxar a imagem do Docker Hub, tem uma certa latência. Então, eu consigo trabalhar com estratégias de cache, que acelera muito mais o deploy. Aí eu publico a nova imagem lá. A nova versão é publicada num repositório de infraestrutura do Kubernetes, porque a gente trabalha com Infra-S Code. Aí quando esse repositório aqui tem uma nova versão, cai para uma ferramenta chamada de Argo CD. Na verdade eu falei em Fresh Code, a gente não trabalha com Fresh Code, a gente trabalha com GitOps. Toda a nossa infraestrutura é versionada nesse repositório aqui. Todas as mudanças, os deployments do Kubernetes, todas as configurações, elas ficam no repositório. Então, quando tem uma nova mudança, essa ferramenta que é a Argo CD, ela captura essa nova mudança, já deixa disponível lá. Você tem uma nova mudança. Quer publicar? Ela vai, publica. Ou no Kubernetes de homologação, ou no Kubernetes de produção. A gente não tem o AutoSync. No caso, a gente tem o AutoSync para poder pegar as configurações, mas não tem deploy automático. Isso é perigoso. Você usa o Helm? Usando o Helm? Não, a gente não está usando o Helm. A gente está usando o que apenas usemos. Helm é uma próxima etapa porque a gente tem esses dois ambientes aqui e tem muita replicação de código no momento, mas usar o Helm ajudaria bastante. A gente não está usando o Helm no momento. Mas aí a gente tem só um lugar que eu acesso lá. Ah, tem a nova versão. Beleza, publico. Aí ele vai lá e instala as novas versões, puxando aqui as imagens no Kubernetes de produção de homolog, beleza deu certo? Não, não deu certo? Faça o rollback o rollback vai afetar aqui o nosso repositório de infraestrutura se eu mudar recursos que a aplicação está usando, CPU de memória e tudo mais, tudo fica aqui. Eu consigo reverter não só a minha aplicação, mas como a minha infraestrutura para qualquer lugar do tempo. Outro dia, por exemplo, nós fizemos uma atualização do Kubernetes, que até a gente teve que comunicar a vocês que ia ficar indisponível, não porque tinha que fazer alguma mudança que era mais por conta de uma configuração do Nginx e geração dos certificados, né? Porque a gente rastreia alguns IPs, tem alguma configuração interna aqui pra poder evitar abuso, porque tem pessoas que compartilham contas e tal, a gente olha algumas coisas assim. Então tinha que desativar uma configuração do Nginx, fazer a geração de certificados e habilitar de novo, mas a gente tinha toda a nossa infraestrutura versionada, fizemos a migração, atualizou o que tinha que ser atualizado, beleza. Então, ter um processo de CI, de gerar os novos artefatos da aplicação e de fazer esse deploy bem organizado, ajuda a entregar aplicações com mais qualidade. Talvez a sua aplicação tenha um CI e um CD ajustados, mas tem muitas aplicações ainda não feitas com nada disso. Tem muitas empresas, vocês não têm noção, vocês não têm noção de empresas que nem conhecem CICD. Empresa que usa FTP para poder fazer deploy. Ah, você tem a nova versão ali? Logga com o FTP lá dentro do servidor e joga. Tem, tá? Tem muita Tá, tem muita empresa. E aí sempre dá... Eu recebo muita dúvida. Luiz, eu tenho aqui o FTP, mas aí atualiza os arquivos, gera problema e tudo mais. Ah, por que você não gera pelo menos uma GitHub Action pra poder fazer? Ah, tem como fazer? Sim, às vezes a gente trabalha com tantas tecnologias novas e que resolvem problemas, mas tem a realidade de muitas empresas e profissionais que eles não têm nem noção que essas coisas existem. Empresa grande? Empresa grande e empresa também... Empresa... Pública, tá? Posso falar nome de forma alguma. Empresa grande pública. Tô falando que é só, tem empresas privadas também. Mas tem, tô falando desse caso, de uma empresa grande pública que usa FTP. Se eu falar aqui, amanhã o STF me processa, né? Sei lá, fugir do... Tô zoando. A gente finalizando esse curso aqui, a gente vai ser mais bem capacitado do que 60% do mercado? Não, é assim, vocês que estão aqui, vocês não têm noção o quanto vocês estão sendo privilegiados, tá? Saiba disso. Vocês estão à frente de uma leva de desenvolvedores que, assim, às vezes eu fico pensando, assim, como a gente vocês estão à frente de uma leva de desenvolvedores que assim às vezes eu fico pensando como a gente fica nichado de... você chega e conversa com alguém que não conhece Docker você vai falar, pô, mas onde você vive? você tá dentro da caverna? alguma coisa assim? ó, tem profissionais que não conhecem o GitHub é sério o GitHub sério sério conheço profissionais que não conhecem o GitHub conheço faculdades em pleno 2025 que se você perguntar também pro professor se usa o GitHub ah, não, já ouvi falar mas não vejo importância mas aí deve ser aqueles caras que trabalham com totos a vida inteira, é possível. É, mas assim, é o que é interessante, tipo assim, a gente está aqui numa formação, não sei se tem muitas pessoas aqui da liderança técnica, tem pessoal do MBA, mas parem pra poder pensar o quanto vocês estão sendo privilegiados, o quanto vocês estão procurando se diferenciar no mercado. Só para vocês estarem em uma live dessa, adquirir uma formação como essa, estarem aí buscando conteúdos com a gente e tudo mais. E pensando em nível de IA. A gente vai ter daqui a alguns anos uma série de profissionais que vão usar IA. Ah, vou aqui no chat EPT, ah, gera um CRUD para mim, sei lá. Daqui a alguns anos, sim, vão ter muitos profissionais, assim. O conhecimento hoje, ele é muito difundido, mas são muitas opções também, muitas pessoas não conseguem acessar com internet e tudo mais. Então, muitas empresas não têm esse acesso, não têm essa consciência de o quão isso aqui vai ser benéfico. Então, boas práticas. Automatize o máximo que você puder do CICD. Rod testes, ferramentas de qualidade de código, Sonar Cube, qualquer coisa, IA, quees, ferramentas de qualidade de código, Sonar Cube, qualquer coisa, e há que já tem ferramentas nesse sentido. Faça um versionamento consistente dos seus artefatos para que você consiga fazer rollbacks facilmente, mas não mantenha muitas versões. A gente mantém somente quatro releases, porque a gente não precisa mais, isso ajuda a evitar baratear o armazenamento das imagens também. Uma coisa que a gente faz é otimizar bastante o tamanho das imagens Docker. Documentação de código é essencial para saber tudo o que está acontecendo, para as novas pessoas que estão entrando, para os times que vão ser realocados, para a empresa, de fato, saber de onde ela estava e para onde ela vai e quais as decisões que ela tem que tomar. E feedback rápido, né? Se a ICD é bom, porque você já tem um feedback ali na hora. Você tem a correção, a nova feature, subiu, já está no ar, já podemos fazer os testes, não, não deu certo, retrocede, ah, deu bug lá, retrocede, esse feedback rápido, ele melhora a qualidade de todo o serviço. Então, conclusões, crie um plano de ações para tudo isso, se você tem as suas aplicações, foi o que a gente fez e continuou fazendo, não dá para implementar tudo isso aqui de uma vez, crie um plano de aações do que é mais necessário. Muitas vezes você não tem testes. Pessoas já falaram aqui que não tem testes nas aplicações. Testes já seria o primeiro passo. Criar um diagnóstico é importante também para você poder saber quais pontos você vai ter que refatorar, se é código, se é cache, se é banco de dados. Coloque prioridades você não vai conseguir fazer tudo se tudo é prioritário nada é prioritário vejo muitos em empresa mas tudo aqui é prioritar por mais tão por onde a gente vai começar o que é mais necessário fazer escolher as partes mais importantes na performance e testes já vai fazer uma grande diferença, acredite. Se você já entrega performance da sua aplicação, você vai reduzir custos, vai ter uma melhor experiência para o usuário com testes, vai evitar bugs, vai evitar ruídos, vai gastar muito menos tempo. E é isso, essa apresentação aqui, pessoal, eu tinha feito ela num evento da CodeCon no ano passado, quando o Leonan quis trazer esse case mais real. Eu pensei logo nisso, porque agora vocês conhecem um pouco mais dos nossos desafios, com esse monolito que gera muito resultado, mas muitos problemas também. né? Mas é isso que eu queria passar pra vocês. Acabou com essa discussão. Eu falei que não ia até as 11 horas. Acabou indo, né? Minha esposa daqui a pouco vai me... Vou dormir no sofá hoje. Mas, né? A gente alongou. A gente conversou sobre ar, conversou um monte de coisas. Muito bom isso. Mesmo que muitas pessoas foram embora porque todo mundo tem as suas necessidades, a noite amanhã todo mundo tem que trabalhar mas acho que foi um dos bate-papos mais tops que eu já fiz aí, porque assim, eu curto demais quando vocês interrompem e vão fazendo o assunto vocês mesmos foram construindo aí essa palestra como que você aprendeu tudo isso em termos de performance, gargalos e foi com os problemas da vida mesmo ali? foi batendo um problema, você foi caçando, viu onde era e a solução, procura em livro, procura ajuda pro meu caso, eu vou contar um pouco da minha história até vou descompartilhar aqui a tela pra gente poder ir indo pro fim eu já contei em algumas lives eu estudei sistemas de informação e no sexto período eu abri uma software house com outro cara que eu conheci na faculdade e a gente começou a desenvolver várias coisas. Isso me ajudou até terminar a faculdade bem ali, né? Porque chegou, tipo, no sétimo período e oitavo, tinham coisas técnicas, o professor ia passar, eu já tava bem à frente ali, já sabia, por exemplo, a autenticação, sessão em CUC, HTTP, essas coisas, né? Por exemplo, autenticação, sessão em cookie, HTTP, essas coisas, né? Acabou a faculdade, comecei a desenvolver tudo que é tipo de sistemas e tudo mais, e eu me achava capacitado. Mas, obviamente, eu era um jovem de 20, 21 anos, e eu tive a minha primeira frustração com a área, porque eu peguei um projeto muito grande pra poder desenvolver um software pra um hospital veterinário. E eu não consegui entregar o projeto, porque eu determinei um prazo irreal, não tinha consciência disso. Quando eu comecei a desenvolver, eu via que o buraco era muito mais embaixo. desenvolver, eu via que o buraco era muito mais embaixo foi a única vez assim que eu fiquei quase um burnout de pensar o que eu ia fazer com a minha vida ou coisas do tipo você começa a pensar um monte de besteiras e tudo mais eu encerrei esse projeto o dono do hospital começou a entrar em atrito achando que eu tava querendo enrolar ele ou algo do tipo, falei, não, vamos fechar o contrato te devolvo todo o valor e tudo mais eu fiquei muito frustrado nessa época porque eu vi exatamente as minhas deficiências eu vi que a faculdade ela me deu muitos fundamentos, mas pra você poder ir bem no mercado nessa área de empreendedorismo a parte técnica minha tava deixando muito a desejar, no sentido assim, eu sabia muito algoritmo, eu conseguia resolver os problemas, mas me faltava ainda conhecimento de usar frameworks, de ter a malícia mesmo da profissão, de tudo isso que a gente está falando. Nessa época não tinha containers, nada disso, né? Então eu fechei minha empresa, pensei em desistir da área, fiquei fora dois anos, né? Nesse meio tempo, eu acabei montando um negócio de manutenção de computadores, instalação de servidores e tudo mais, porque eu já tinha um conhecimento ali e tal. Isso me sustentou por um tempo, e aí, assim, você vai sentar na cabeça eu era jovem, né? O bom é que eu errei muito quando eu era novo. Então, eu fui me reciclando. Eu comecei a estudar programação novamente, comecei a conversar com algumas pessoas, e aí comecei a pegar alguns projetos pequenos até o ponto que antes até de encerrar a minha empresa ou melhor, de voltar com a minha empresa mesmo de novo eu comecei a prestar alguns serviços freelancer e comecei a prestar consultoria até o ponto que eu encerrei minha manutenção de computadores e voltei com a minha empresa de novo e aí eu comecei Encerrei minha manutenção de computadores E voltei com a minha empresa de novo E aí Eu comecei A desenvolver todo tipo de coisa de novo Sites, sistemas Desktop, o que for necessário E nunca parei De estudar mais E as coisas foram Vindo pra mim Exatamente porque Essa é uma cicatriz muito forte. Ela tá presente em mim até hoje. Então, assim, isso me trouxe muita maturidade. E as consultorias que eu fui prestando e tudo isso em conjunto me deram uma bagagem, né? São aquelas cicatrizes que vão fazendo você ter essa experiência. Até que, num determinado tempo, o caminho me juntou com o Wesley bagagem, né, são aquelas cicatrizes que vão fazendo você ter essa experiência, até que num determinado tempo, o caminho me juntou com Wesley e acabou que eu gostava muito dessa área educacional também, já tinha dado aula e acabei migrando, abandonei minha empresa, fechei e juntei os anéis aí com Wesley, com todo o pessoal. Então, assim, pra mim foi justamente o grande divisor de águas foi eu não ter desistido mas ter acontecido isso comigo eu acho que se não tivesse acontecido essa falha que eu, feriu demais o meu orgulho, né, a gente não gosta que fere o orgulho da gente, mas pra mim fez uma grande diferença, porque até hoje eu sei que eu tenho que estudar eu tenho que correr atrás eu tenho que entender muito bem as coisas que estão acontecendo, isso ficou meio que uma marca, sabe? Então isso ditou as regras de como que eu faço as minhas coisas hoje em dia então isso me fez me movimentar. Talvez se eu tivesse começado, entrado em alguma empresa como júnior, eu poderia ter tido um caminho assim que até hoje eu estaria patinando, sabe? Não sabendo aonde que eu estava. E a Full Cycle nesse nesse caso eu fico pensando assim se tivesse uma Full Psycho na época ou alguém que me mentorasse ou algo assim é tipo assim, eu ia pra faculdade de bicicleta não tinha dinheiro, eu fiz faculdade com bolsa minha família era muito pobre eu conseguia, é pro-uni na época pra poder estudar então tudo que eu assim, eu fui conseguindo, foi tipo batendo cabeça, ah, me machuquei, deixa eu ir pra outro lugar. Então, isso me ajudou bastante. Então, eu vejo, assim, que o sentido foi, acho que vocês seguem o Akita, não sei quem curte, enfim, tem gente que não gosta dele por questão aí de algumas coisas que ele se manifesta, mas uma coisa que ele falou, quando ele disse isso, eu falei, eu pratico isso, eu não sabia, que é tomar as suas próprias decisões. Eu nunca fui da pessoa que gostou de terceirizar para outras pessoas. Então, por exemplo, na hora de tomar uma decisão de fazer uma implementação, eu banco ela, mas depois eu colho as responsabilidades do que aconteceu então isso de certa forma é bom porque te ensina muito bem do que aconteceu eu tomei uma implementação aqui que acabou com o banco então deixa eu olhar o que aconteceu eu vou olhar muito bem vou entender e tudo mais Vou buscar conhecimento disso Para poder resolver esse problema Aí também esse lado de consultoria me ajudou bastante Porque assim, eu vi muitas, todo tipo de empresa Empresas que problemas eram justamente código Outras eram banco de dados Outras vezes era gestão de projetos. Peguei muitas empresas que às vezes não conseguiam organizar muito bem tarefas, enfim, já peguei todo tipo de bucho. Isso ajuda bastante também. Construir, você vê o ambiente ali, você está com o olhar de fora, né? A empresa, às vezes, ela está com o olhar interno e ela não consegue enxergar muito bem os problemas agora chega uma pessoa e ela está de fora ela não tem muito compromisso com agradar você está ali para poder fazer o seu trabalho entender onde estão os problemas e apontar as questões então isso me ajudou muito galera, muito obrigado a todo mundo que participou mais uma vez um grande abraço e até a próxima, fiquem ligados lá no calendário que logo logo já vai ter coisa nova abraço, valeu Luiz