◦ Testes lentos, filas para deploy, incidentes constantes, testes manuais, conflitos em merges… • Bugs em produção são comuns ◦ E é normal levar dias para achar e consertar eles • Baixa escalabilidade e desperdício de recursos ◦ Uma parte do sistema precisa de mais memória, outra de mais CPU… • Baixa resiliência e tolerância a falhas • Sistema com techstack e bibliotecas desatualizadas Como saber se você está em um?
• E é possível atrasar a deterioração do monolito, usando: ◦ Boas práticas de desenvolvimento de software ◦ Código modular, com responsabilidades bem definidas ◦ Boa cobertura de testes automatizados ◦ Equilíbrio de foco entre entrega de features e melhorias de débitos técnicos Disclaimers!
como construir a arquitetura do zero, dados os requisitos de produto ou a partir de um monolito. • Mas e se a própria arquitetura de microserviços se torna legada? Complexity Hell
você também tem que entender várias bases de código e a relação entre elas • Baixa produtividade ◦ Dependências entre serviços, serviços inchados, responsabilidades espalhadas… • Bugs em produção são comuns ◦ Mas agora eles se espalham entre serviços • Baixa escalabilidade e desperdício de recursos ◦ Uma parte de um serviço precisa escalar com requisições sync, outra com async, outra usa mais CPU… • Baixa resiliência e tolerância a falhas ◦ Requisições síncronas criam gargalos e dependências temporais • Sistema com techstack e bibliotecas desatualizadas Os sintomas são parecidos, mudam os detalhes
microserviços. ◦ modularidade, testes automatizados, boas práticas, não acumular débitos… • Quanto mais complexa a arquitetura, mais rápido ela se tornará legada. ◦ Busque simplicidade! Cuidados
Diferentes decisões técnicas acarretam diferentes complexidades. • Existe pouca relação entre os requisitos funcionais e a escolha de arquitetura. Decisões Técnicas
a arquitetura, então para que ela serve? • A arquitetura define os requisitos não-funcionais do produto, ou seja, a qualidade do sistema. ◦ A decomposição das responsabilidades da aplicação e os relacionamentos entre elas determinam as -ilities. Requisitos Não-Funcionais
tem prós e contras. • Perguntas a serem respondidas: ◦ Os ‘contras’ são aceitáveis? ◦ Os ‘prós’ são necessários? ▪ Cuidado com a otimização prematura! Trade-Offs de Arquitetura
produto cresce. ◦ Não tente criar algo perfeito e eterno • O que não quer dizer que é para fazer de qualquer jeito! • Não temos como impedir as mudanças, mas podemos guiá-las e planejar para elas. O que é arquitetura?
muito semelhantes a monolitos legados… ◦ …mas com algumas complexidades a mais • Importante ter um mindset de “arquitetura sacrificável” ◦ O código precisar ser sacrificado é sinal de sucesso do produto ◦ Ainda é importante ter qualidade, para o código se deteriorar mais lentamente ◦ Modularidade é essencial ◦ Evita otimização prematura
Bang” ◦ Além dos riscos ao colocar em produção, também há o risco de nunca colocar em produção. Por isso, faça mudanças incrementais. “Se você fizer uma refatoração Big Bang, a única coisa garantida é o Big Bang.” Martin Fowler
com a aplicação ‘Call Records API’ ◦ Github: shorturl.at/ehp03 ◦ “Uma API que recebe detalhes de chamadas telefônicas e calcula a conta mensal para um número de telefone”
facilmente quais são os domínios que já existem no código. • Passos: ◦ Entender a estrutura do programa dado só classes, métodos e como eles se comunicam. ◦ Considerar apenas código que implementa regras de negócio, e que é chamado por outras partes do código (‘público’). ◦ Categorizar as dependências em grupos. ◦ Não se prenda a detalhes técnicos da linguagem ou do algoritmo.
os domínios do código interagem, para mapear os contextos que existem no código. • Passos: ◦ Cada componente aparece apenas uma vez ◦ Ligue cada componente ao componentes que ele interage ◦ Organize o diagrama para os componentes ficarem em ‘clusters’, tentando não deixar que as linhas se sobreponham ▪ Se as linhas estão muitos sobrepostas, isso indica que o código não está modular, e é boa ideia refatorá-lo para consertar isso antes de quebrá-lo.
implementação dos requisitos pode ser quebrada em domínios • Questões: ◦ Os contextos identificados são sobre quais responsabilidades e entidades? ◦ Um serviço deve ter uma responsabilidade única e bem-definida. Dado isso, esses contextos deveriam estar nesse serviço, ou em outros? ◦ Quais são os requisitos funcionais que esse serviço está implementando? ◦ Quais interações externas ocorrem com esses contextos? ▪ Quais são as chamadas síncronas e assíncronas que o código recebe e faz? ▪ De quais domínios externos essas chamadas fazem parte?
o uso. • Podem receber as mesmas requisições e só um ser usado, ou funcionar como um canário. Service 1 App Service 1 App Service 2 Service 2 App Técnica de Modificação:
1. Adiciona o campo B, sem usar 2. Escrita tanto em A como em B 3. Leitura apenas em B 4. Aguardar/Corrigir bugs 5. Remover campo A Técnica de Modificação: